00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00029
00030
00031
00032 #include <ctype.h>
00033 #include <vlc/vlc.h>
00034 #include <vlc/decoder.h>
00035 #include <vlc_filter.h>
00036 #include <vlc_image.h>
00037
00038 static picture_t *ImageRead( image_handler_t *, block_t *,
00039 video_format_t *, video_format_t * );
00040 static picture_t *ImageReadUrl( image_handler_t *, const char *,
00041 video_format_t *, video_format_t * );
00042 static block_t *ImageWrite( image_handler_t *, picture_t *,
00043 video_format_t *, video_format_t * );
00044 static int ImageWriteUrl( image_handler_t *, picture_t *,
00045 video_format_t *, video_format_t *, const char * );
00046
00047 static picture_t *ImageConvert( image_handler_t *, picture_t *,
00048 video_format_t *, video_format_t * );
00049 static picture_t *ImageFilter( image_handler_t *, picture_t *,
00050 video_format_t *, const char *psz_module );
00051
00052 static decoder_t *CreateDecoder( vlc_object_t *, video_format_t * );
00053 static void DeleteDecoder( decoder_t * );
00054 static encoder_t *CreateEncoder( vlc_object_t *, video_format_t *,
00055 video_format_t * );
00056 static void DeleteEncoder( encoder_t * );
00057 static filter_t *CreateFilter( vlc_object_t *, es_format_t *,
00058 video_format_t *, const char * );
00059 static void DeleteFilter( filter_t * );
00060
00061 static vlc_fourcc_t Ext2Fourcc( const char * );
00062
00063
00068 image_handler_t *__image_HandlerCreate( vlc_object_t *p_this )
00069 {
00070 image_handler_t *p_image = malloc( sizeof(image_handler_t) );
00071
00072 memset( p_image, 0, sizeof(image_handler_t) );
00073 p_image->p_parent = p_this;
00074
00075 p_image->pf_read = ImageRead;
00076 p_image->pf_read_url = ImageReadUrl;
00077 p_image->pf_write = ImageWrite;
00078 p_image->pf_write_url = ImageWriteUrl;
00079 p_image->pf_convert = ImageConvert;
00080 p_image->pf_filter = ImageFilter;
00081
00082 return p_image;
00083 }
00084
00089 void image_HandlerDelete( image_handler_t *p_image )
00090 {
00091 if( !p_image ) return;
00092
00093 if( p_image->p_dec ) DeleteDecoder( p_image->p_dec );
00094 if( p_image->p_enc ) DeleteEncoder( p_image->p_enc );
00095 if( p_image->p_filter ) DeleteFilter( p_image->p_filter );
00096
00097 free( p_image );
00098 }
00099
00105 static picture_t *ImageRead( image_handler_t *p_image, block_t *p_block,
00106 video_format_t *p_fmt_in,
00107 video_format_t *p_fmt_out )
00108 {
00109 picture_t *p_pic = NULL, *p_tmp;
00110
00111
00112 if( p_image->p_dec &&
00113 p_image->p_dec->fmt_in.i_codec != p_fmt_in->i_chroma )
00114 {
00115 DeleteDecoder( p_image->p_dec );
00116 p_image->p_dec = 0;
00117 }
00118
00119
00120 if( !p_image->p_dec )
00121 {
00122 p_image->p_dec = CreateDecoder( p_image->p_parent, p_fmt_in );
00123 if( !p_image->p_dec ) return NULL;
00124 }
00125
00126 p_block->i_pts = p_block->i_dts = mdate();
00127 while( (p_tmp = p_image->p_dec->pf_decode_video( p_image->p_dec, &p_block ))
00128 != NULL )
00129 {
00130 if ( p_pic != NULL )
00131 p_pic->pf_release( p_pic );
00132 p_pic = p_tmp;
00133 }
00134
00135 if( p_pic == NULL )
00136 {
00137 msg_Warn( p_image->p_parent, "no image decoded" );
00138 return 0;
00139 }
00140
00141 if( !p_fmt_out->i_chroma )
00142 p_fmt_out->i_chroma = p_image->p_dec->fmt_out.video.i_chroma;
00143 if( !p_fmt_out->i_width && p_fmt_out->i_height )
00144 p_fmt_out->i_width = p_fmt_out->i_height
00145 * p_image->p_dec->fmt_out.video.i_aspect
00146 / VOUT_ASPECT_FACTOR;
00147 if( !p_fmt_out->i_height && p_fmt_out->i_width )
00148 p_fmt_out->i_height = p_fmt_out->i_width * VOUT_ASPECT_FACTOR
00149 / p_image->p_dec->fmt_out.video.i_aspect;
00150 if( !p_fmt_out->i_width )
00151 p_fmt_out->i_width = p_image->p_dec->fmt_out.video.i_width;
00152 if( !p_fmt_out->i_height )
00153 p_fmt_out->i_height = p_image->p_dec->fmt_out.video.i_height;
00154
00155
00156 if( p_image->p_dec->fmt_out.video.i_chroma != p_fmt_out->i_chroma ||
00157 p_image->p_dec->fmt_out.video.i_width != p_fmt_out->i_width ||
00158 p_image->p_dec->fmt_out.video.i_height != p_fmt_out->i_height )
00159 {
00160 if( p_image->p_filter )
00161 if( p_image->p_filter->fmt_in.video.i_chroma !=
00162 p_image->p_dec->fmt_out.video.i_chroma ||
00163 p_image->p_filter->fmt_out.video.i_chroma != p_fmt_out->i_chroma )
00164 {
00165
00166 DeleteFilter( p_image->p_filter );
00167 p_image->p_filter = 0;
00168 }
00169
00170
00171 if( !p_image->p_filter )
00172 {
00173 p_image->p_filter =
00174 CreateFilter( p_image->p_parent, &p_image->p_dec->fmt_out,
00175 p_fmt_out, NULL );
00176
00177 if( !p_image->p_filter )
00178 {
00179 p_pic->pf_release( p_pic );
00180 return NULL;
00181 }
00182 }
00183 else
00184 {
00185
00186 p_image->p_filter->fmt_in = p_image->p_dec->fmt_out;
00187 p_image->p_filter->fmt_out = p_image->p_dec->fmt_out;
00188 p_image->p_filter->fmt_out.i_codec = p_fmt_out->i_chroma;
00189 p_image->p_filter->fmt_out.video = *p_fmt_out;
00190 }
00191
00192 p_pic = p_image->p_filter->pf_video_filter( p_image->p_filter, p_pic );
00193 *p_fmt_out = p_image->p_filter->fmt_out.video;
00194 }
00195 else *p_fmt_out = p_image->p_dec->fmt_out.video;
00196
00197 return p_pic;
00198 }
00199
00200 static picture_t *ImageReadUrl( image_handler_t *p_image, const char *psz_url,
00201 video_format_t *p_fmt_in,
00202 video_format_t *p_fmt_out )
00203 {
00204 block_t *p_block;
00205 picture_t *p_pic;
00206 FILE *file;
00207 int i_size;
00208
00209 file = fopen( psz_url, "rb" );
00210 if( !file )
00211 {
00212 msg_Dbg( p_image->p_parent, "could not open file %s for reading",
00213 psz_url );
00214 return NULL;
00215 }
00216
00217 fseek( file, 0, SEEK_END );
00218 i_size = ftell( file );
00219 fseek( file, 0, SEEK_SET );
00220
00221 p_block = block_New( p_image->p_parent, i_size );
00222 fread( p_block->p_buffer, sizeof(char), i_size, file );
00223 fclose( file );
00224
00225 if( !p_fmt_in->i_chroma )
00226 {
00227
00228 p_fmt_in->i_chroma = Ext2Fourcc( psz_url );
00229 }
00230
00231 p_pic = ImageRead( p_image, p_block, p_fmt_in, p_fmt_out );
00232
00233 return p_pic;
00234 }
00235
00241 void PicRelease( picture_t *p_pic ){};
00242
00243 static block_t *ImageWrite( image_handler_t *p_image, picture_t *p_pic,
00244 video_format_t *p_fmt_in,
00245 video_format_t *p_fmt_out )
00246 {
00247 block_t *p_block;
00248 void (*pf_release)( picture_t * );
00249
00250
00251 if( p_image->p_enc &&
00252 ( p_image->p_enc->fmt_out.i_codec != p_fmt_out->i_chroma ||
00253 p_image->p_enc->fmt_out.video.i_width != p_fmt_out->i_width ||
00254 p_image->p_enc->fmt_out.video.i_height != p_fmt_out->i_height ) )
00255 {
00256 DeleteEncoder( p_image->p_enc );
00257 p_image->p_enc = 0;
00258 }
00259
00260
00261 if( !p_image->p_enc )
00262 {
00263 p_image->p_enc = CreateEncoder( p_image->p_parent,
00264 p_fmt_in, p_fmt_out );
00265 if( !p_image->p_enc ) return NULL;
00266 }
00267
00268
00269 if( p_image->p_enc->fmt_in.video.i_chroma != p_fmt_in->i_chroma ||
00270 p_image->p_enc->fmt_in.video.i_width != p_fmt_in->i_width ||
00271 p_image->p_enc->fmt_in.video.i_height != p_fmt_in->i_height )
00272 {
00273 picture_t *p_pif;
00274
00275 if( p_image->p_filter )
00276 if( p_image->p_filter->fmt_in.video.i_chroma != p_fmt_in->i_chroma ||
00277 p_image->p_filter->fmt_out.video.i_chroma !=
00278 p_image->p_enc->fmt_in.video.i_chroma )
00279 {
00280
00281 DeleteFilter( p_image->p_filter );
00282 p_image->p_filter = 0;
00283 }
00284
00285
00286 if( !p_image->p_filter )
00287 {
00288 es_format_t fmt_in;
00289 es_format_Init( &fmt_in, VIDEO_ES, p_fmt_in->i_chroma );
00290 fmt_in.video = *p_fmt_in;
00291
00292 p_image->p_filter =
00293 CreateFilter( p_image->p_parent, &fmt_in,
00294 &p_image->p_enc->fmt_in.video, NULL );
00295
00296 if( !p_image->p_filter )
00297 {
00298 return NULL;
00299 }
00300 }
00301 else
00302 {
00303
00304 p_image->p_filter->fmt_in.i_codec = p_fmt_in->i_chroma;
00305 p_image->p_filter->fmt_out.video = *p_fmt_in;
00306 p_image->p_filter->fmt_out.i_codec =p_image->p_enc->fmt_in.i_codec;
00307 p_image->p_filter->fmt_out.video = p_image->p_enc->fmt_in.video;
00308 }
00309
00310 pf_release = p_pic->pf_release;
00311 p_pic->pf_release = PicRelease;
00312 p_pif = p_image->p_filter->pf_video_filter( p_image->p_filter, p_pic );
00313 p_pic->pf_release = pf_release;
00314 p_pic = p_pif;
00315 }
00316
00317 p_block = p_image->p_enc->pf_encode_video( p_image->p_enc, p_pic );
00318
00319 if( !p_block )
00320 {
00321 msg_Dbg( p_image->p_parent, "no image encoded" );
00322 return 0;
00323 }
00324
00325 return p_block;
00326 }
00327
00328 static int ImageWriteUrl( image_handler_t *p_image, picture_t *p_pic,
00329 video_format_t *p_fmt_in, video_format_t *p_fmt_out,
00330 const char *psz_url )
00331 {
00332 block_t *p_block;
00333 FILE *file;
00334
00335 if( !p_fmt_out->i_chroma )
00336 {
00337
00338 p_fmt_out->i_chroma = Ext2Fourcc( psz_url );
00339 }
00340
00341 file = fopen( psz_url, "wb" );
00342 if( !file )
00343 {
00344 msg_Dbg( p_image->p_parent, "could not open file %s for writing",
00345 psz_url );
00346 return VLC_EGENERIC;
00347 }
00348
00349 p_block = ImageWrite( p_image, p_pic, p_fmt_in, p_fmt_out );
00350
00351 if( p_block )
00352 {
00353 fwrite( p_block->p_buffer, sizeof(char), p_block->i_buffer, file );
00354 block_Release( p_block );
00355 }
00356
00357 fclose( file );
00358
00359 return p_block ? VLC_SUCCESS : VLC_EGENERIC;
00360 }
00361
00367 static picture_t *ImageConvert( image_handler_t *p_image, picture_t *p_pic,
00368 video_format_t *p_fmt_in,
00369 video_format_t *p_fmt_out )
00370 {
00371 void (*pf_release)( picture_t * );
00372 picture_t *p_pif;
00373
00374 if( !p_fmt_out->i_width && !p_fmt_out->i_height &&
00375 p_fmt_out->i_sar_num && p_fmt_out->i_sar_den &&
00376 p_fmt_out->i_sar_num * p_fmt_in->i_sar_den !=
00377 p_fmt_out->i_sar_den * p_fmt_in->i_sar_num )
00378 {
00379 p_fmt_out->i_width =
00380 p_fmt_in->i_sar_num * (int64_t)p_fmt_out->i_sar_den *
00381 p_fmt_in->i_width / p_fmt_in->i_sar_den / p_fmt_out->i_sar_num;
00382 p_fmt_out->i_visible_width =
00383 p_fmt_in->i_sar_num * (int64_t)p_fmt_out->i_sar_den *
00384 p_fmt_in->i_visible_width / p_fmt_in->i_sar_den /
00385 p_fmt_out->i_sar_num;
00386 }
00387
00388 if( !p_fmt_out->i_chroma ) p_fmt_out->i_chroma = p_fmt_in->i_chroma;
00389 if( !p_fmt_out->i_width )
00390 p_fmt_out->i_width = p_fmt_out->i_visible_width = p_fmt_in->i_width;
00391 if( !p_fmt_out->i_height )
00392 p_fmt_out->i_height = p_fmt_out->i_visible_height = p_fmt_in->i_height;
00393 if( !p_fmt_out->i_sar_num ) p_fmt_out->i_sar_num = p_fmt_in->i_sar_num;
00394 if( !p_fmt_out->i_sar_den ) p_fmt_out->i_sar_den = p_fmt_in->i_sar_den;
00395 if( !p_fmt_out->i_aspect ) p_fmt_out->i_aspect = p_fmt_in->i_aspect;
00396
00397 if( p_image->p_filter )
00398 if( p_image->p_filter->fmt_in.video.i_chroma != p_fmt_in->i_chroma ||
00399 p_image->p_filter->fmt_out.video.i_chroma != p_fmt_out->i_chroma )
00400 {
00401
00402 DeleteFilter( p_image->p_filter );
00403 p_image->p_filter = 0;
00404 }
00405
00406
00407 if( !p_image->p_filter )
00408 {
00409 es_format_t fmt_in;
00410 es_format_Init( &fmt_in, VIDEO_ES, p_fmt_in->i_chroma );
00411 fmt_in.video = *p_fmt_in;
00412
00413 p_image->p_filter =
00414 CreateFilter( p_image->p_parent, &fmt_in, p_fmt_out, NULL );
00415
00416 if( !p_image->p_filter )
00417 {
00418 return NULL;
00419 }
00420 }
00421 else
00422 {
00423
00424 p_image->p_filter->fmt_in.video = *p_fmt_in;
00425 p_image->p_filter->fmt_out.video = *p_fmt_out;
00426 }
00427
00428 pf_release = p_pic->pf_release;
00429 p_pic->pf_release = PicRelease;
00430 p_pif = p_image->p_filter->pf_video_filter( p_image->p_filter, p_pic );
00431 p_pic->pf_release = pf_release;
00432
00433 if( p_fmt_in->i_chroma == p_fmt_out->i_chroma &&
00434 p_fmt_in->i_width == p_fmt_out->i_width &&
00435 p_fmt_in->i_height == p_fmt_out->i_height )
00436 {
00437
00438 p_pif = p_image->p_filter->pf_vout_buffer_new( p_image->p_filter );
00439 if( p_pif ) vout_CopyPicture( p_image->p_parent, p_pif, p_pic );
00440 }
00441
00442 return p_pif;
00443 }
00444
00450 static picture_t *ImageFilter( image_handler_t *p_image, picture_t *p_pic,
00451 video_format_t *p_fmt, const char *psz_module )
00452 {
00453 void (*pf_release)( picture_t * );
00454 picture_t *p_pif;
00455
00456
00457 if( !p_image->p_filter )
00458 {
00459 es_format_t fmt;
00460 es_format_Init( &fmt, VIDEO_ES, p_fmt->i_chroma );
00461 fmt.video = *p_fmt;
00462
00463 p_image->p_filter =
00464 CreateFilter( p_image->p_parent, &fmt, &fmt.video, psz_module );
00465
00466 if( !p_image->p_filter )
00467 {
00468 return NULL;
00469 }
00470 }
00471 else
00472 {
00473
00474 p_image->p_filter->fmt_in.video = *p_fmt;
00475 p_image->p_filter->fmt_out.video = *p_fmt;
00476 }
00477
00478 pf_release = p_pic->pf_release;
00479 p_pic->pf_release = PicRelease;
00480 p_pif = p_image->p_filter->pf_video_filter( p_image->p_filter, p_pic );
00481 p_pic->pf_release = pf_release;
00482
00483 return p_pif;
00484 }
00485
00490 static struct
00491 {
00492 vlc_fourcc_t i_codec;
00493 char *psz_ext;
00494
00495 } ext_table[] =
00496 {
00497 { VLC_FOURCC('j','p','e','g'), "jpeg" },
00498 { VLC_FOURCC('j','p','e','g'), "jpg" },
00499 { VLC_FOURCC('l','j','p','g'), "ljpg" },
00500 { VLC_FOURCC('p','n','g',' '), "png" },
00501 { VLC_FOURCC('p','g','m',' '), "pgm" },
00502 { VLC_FOURCC('p','g','m','y'), "pgmyuv" },
00503 { VLC_FOURCC('p','b','m',' '), "pbm" },
00504 { VLC_FOURCC('p','a','m',' '), "pam" },
00505 { VLC_FOURCC('t','g','a',' '), "tga" },
00506 { VLC_FOURCC('b','m','p',' '), "bmp" },
00507 { VLC_FOURCC('p','n','m',' '), "pnm" },
00508 { VLC_FOURCC('x','p','m',' '), "xpm" },
00509 { VLC_FOURCC('x','c','f',' '), "xcf" },
00510 { VLC_FOURCC('p','c','x',' '), "pcx" },
00511 { VLC_FOURCC('g','i','f',' '), "gif" },
00512 { VLC_FOURCC('t','i','f','f'), "tif" },
00513 { VLC_FOURCC('t','i','f','f'), "tiff" },
00514 { VLC_FOURCC('l','b','m',' '), "lbm" },
00515 { 0, NULL }
00516 };
00517
00518 static vlc_fourcc_t Ext2Fourcc( const char *psz_name )
00519 {
00520 int i;
00521
00522 psz_name = strrchr( psz_name, '.' );
00523 if( !psz_name ) return 0;
00524 psz_name++;
00525
00526 for( i = 0; ext_table[i].i_codec; i++ )
00527 {
00528 int j;
00529 for( j = 0; toupper(ext_table[i].psz_ext[j]) == toupper(psz_name[j]);
00530 j++ )
00531 {
00532 if( !ext_table[i].psz_ext[j] && !psz_name[j] )
00533 return ext_table[i].i_codec;
00534 }
00535 }
00536
00537 return 0;
00538 }
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554 static void video_release_buffer( picture_t *p_pic )
00555 {
00556 if( p_pic && p_pic->p_data_orig ) free( p_pic->p_data_orig );
00557 if( p_pic && p_pic->p_sys ) free( p_pic->p_sys );
00558 if( p_pic ) free( p_pic );
00559 }
00560
00561 static picture_t *video_new_buffer( decoder_t *p_dec )
00562 {
00563 picture_t *p_pic = malloc( sizeof(picture_t) );
00564
00565 p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
00566 vout_AllocatePicture( VLC_OBJECT(p_dec), p_pic,
00567 p_dec->fmt_out.video.i_chroma,
00568 p_dec->fmt_out.video.i_width,
00569 p_dec->fmt_out.video.i_height,
00570 p_dec->fmt_out.video.i_aspect );
00571
00572 if( !p_pic->i_planes )
00573 {
00574 free( p_pic );
00575 return 0;
00576 }
00577
00578 p_pic->pf_release = video_release_buffer;
00579 p_pic->i_status = RESERVED_PICTURE;
00580 p_pic->p_sys = NULL;
00581
00582 return p_pic;
00583 }
00584
00585 static void video_del_buffer( decoder_t *p_dec, picture_t *p_pic )
00586 {
00587 if( p_pic && p_pic->p_data_orig ) free( p_pic->p_data_orig );
00588 if( p_pic && p_pic->p_sys ) free( p_pic->p_sys );
00589 if( p_pic ) free( p_pic );
00590 }
00591
00592 static void video_link_picture( decoder_t *p_dec, picture_t *p_pic )
00593 {
00594 }
00595
00596 static void video_unlink_picture( decoder_t *p_dec, picture_t *p_pic )
00597 {
00598 }
00599
00600 static decoder_t *CreateDecoder( vlc_object_t *p_this, video_format_t *fmt )
00601 {
00602 decoder_t *p_dec;
00603
00604 p_dec = vlc_object_create( p_this, VLC_OBJECT_DECODER );
00605 if( p_dec == NULL )
00606 {
00607 msg_Err( p_this, "out of memory" );
00608 return NULL;
00609 }
00610
00611 p_dec->p_module = NULL;
00612 es_format_Init( &p_dec->fmt_in, VIDEO_ES, fmt->i_chroma );
00613 es_format_Init( &p_dec->fmt_out, VIDEO_ES, 0 );
00614 p_dec->fmt_in.video = *fmt;
00615 p_dec->b_pace_control = VLC_TRUE;
00616
00617 p_dec->pf_vout_buffer_new = video_new_buffer;
00618 p_dec->pf_vout_buffer_del = video_del_buffer;
00619 p_dec->pf_picture_link = video_link_picture;
00620 p_dec->pf_picture_unlink = video_unlink_picture;
00621
00622 vlc_object_attach( p_dec, p_this );
00623
00624
00625 p_dec->p_module = module_Need( p_dec, "decoder", "$codec", 0 );
00626 if( !p_dec->p_module )
00627 {
00628 msg_Err( p_dec, "no suitable decoder module for fourcc `%4.4s'.\n"
00629 "VLC probably does not support this image format.",
00630 (char*)&p_dec->fmt_in.i_codec );
00631
00632 DeleteDecoder( p_dec );
00633 return NULL;
00634 }
00635
00636 return p_dec;
00637 }
00638
00639 static void DeleteDecoder( decoder_t * p_dec )
00640 {
00641 vlc_object_detach( p_dec );
00642
00643 if( p_dec->p_module ) module_Unneed( p_dec, p_dec->p_module );
00644
00645 es_format_Clean( &p_dec->fmt_in );
00646 es_format_Clean( &p_dec->fmt_out );
00647
00648 vlc_object_destroy( p_dec );
00649 }
00650
00651 static encoder_t *CreateEncoder( vlc_object_t *p_this, video_format_t *fmt_in,
00652 video_format_t *fmt_out )
00653 {
00654 encoder_t *p_enc;
00655
00656 p_enc = vlc_object_create( p_this, VLC_OBJECT_ENCODER );
00657 if( p_enc == NULL )
00658 {
00659 msg_Err( p_this, "out of memory" );
00660 return NULL;
00661 }
00662
00663 p_enc->p_module = NULL;
00664 es_format_Init( &p_enc->fmt_in, VIDEO_ES, fmt_in->i_chroma );
00665 p_enc->fmt_in.video = *fmt_in;
00666 if( fmt_out->i_width > 0 && fmt_out->i_height > 0 )
00667 {
00668 p_enc->fmt_in.video.i_width = fmt_out->i_width;
00669 p_enc->fmt_in.video.i_height = fmt_out->i_height;
00670
00671 if( fmt_out->i_visible_width > 0 &&
00672 fmt_out->i_visible_height > 0 )
00673 {
00674 p_enc->fmt_in.video.i_visible_width = fmt_out->i_visible_width;
00675 p_enc->fmt_in.video.i_visible_height = fmt_out->i_visible_height;
00676 }
00677 else
00678 {
00679 p_enc->fmt_in.video.i_visible_width = fmt_out->i_width;
00680 p_enc->fmt_in.video.i_visible_height = fmt_out->i_height;
00681 }
00682 }
00683 else if( fmt_out->i_sar_num && fmt_out->i_sar_den &&
00684 fmt_out->i_sar_num * fmt_in->i_sar_den !=
00685 fmt_out->i_sar_den * fmt_in->i_sar_num )
00686 {
00687 p_enc->fmt_in.video.i_width =
00688 fmt_in->i_sar_num * (int64_t)fmt_out->i_sar_den * fmt_in->i_width /
00689 fmt_in->i_sar_den / fmt_out->i_sar_num;
00690 p_enc->fmt_in.video.i_visible_width =
00691 fmt_in->i_sar_num * (int64_t)fmt_out->i_sar_den *
00692 fmt_in->i_visible_width / fmt_in->i_sar_den / fmt_out->i_sar_num;
00693 }
00694
00695 p_enc->fmt_in.video.i_frame_rate = 25;
00696 p_enc->fmt_in.video.i_frame_rate_base = 1;
00697
00698 es_format_Init( &p_enc->fmt_out, VIDEO_ES, fmt_out->i_chroma );
00699 p_enc->fmt_out.video = *fmt_out;
00700 p_enc->fmt_out.video.i_width = p_enc->fmt_in.video.i_width;
00701 p_enc->fmt_out.video.i_height = p_enc->fmt_in.video.i_height;
00702
00703 vlc_object_attach( p_enc, p_this );
00704
00705
00706 p_enc->p_module = module_Need( p_enc, "encoder", 0, 0 );
00707 if( !p_enc->p_module )
00708 {
00709 msg_Err( p_enc, "no suitable encoder module for fourcc `%4.4s'.\n"
00710 "VLC probably does not support this image format.",
00711 (char*)&p_enc->fmt_out.i_codec );
00712
00713 DeleteEncoder( p_enc );
00714 return NULL;
00715 }
00716 p_enc->fmt_in.video.i_chroma = p_enc->fmt_in.i_codec;
00717
00718 return p_enc;
00719 }
00720
00721 static void DeleteEncoder( encoder_t * p_enc )
00722 {
00723 vlc_object_detach( p_enc );
00724
00725 if( p_enc->p_module ) module_Unneed( p_enc, p_enc->p_module );
00726
00727 es_format_Clean( &p_enc->fmt_in );
00728 es_format_Clean( &p_enc->fmt_out );
00729
00730 vlc_object_destroy( p_enc );
00731 }
00732
00733 static filter_t *CreateFilter( vlc_object_t *p_this, es_format_t *p_fmt_in,
00734 video_format_t *p_fmt_out,
00735 const char *psz_module )
00736 {
00737 filter_t *p_filter;
00738
00739 p_filter = vlc_object_create( p_this, VLC_OBJECT_FILTER );
00740 vlc_object_attach( p_filter, p_this );
00741
00742 p_filter->pf_vout_buffer_new =
00743 (picture_t *(*)(filter_t *))video_new_buffer;
00744 p_filter->pf_vout_buffer_del =
00745 (void (*)(filter_t *, picture_t *))video_del_buffer;
00746
00747 p_filter->fmt_in = *p_fmt_in;
00748 p_filter->fmt_out = *p_fmt_in;
00749 p_filter->fmt_out.i_codec = p_fmt_out->i_chroma;
00750 p_filter->fmt_out.video = *p_fmt_out;
00751 p_filter->p_module = module_Need( p_filter, "video filter2", psz_module,
00752 0 );
00753
00754 if( !p_filter->p_module )
00755 {
00756 msg_Dbg( p_filter, "no video filter found" );
00757 DeleteFilter( p_filter );
00758 return NULL;
00759 }
00760
00761 return p_filter;
00762 }
00763
00764 static void DeleteFilter( filter_t * p_filter )
00765 {
00766 vlc_object_detach( p_filter );
00767
00768 if( p_filter->p_module ) module_Unneed( p_filter, p_filter->p_module );
00769
00770 es_format_Clean( &p_filter->fmt_in );
00771 es_format_Clean( &p_filter->fmt_out );
00772
00773 vlc_object_destroy( p_filter );
00774 }