| 222 | | return NULL; |
|---|
| | 228 | block_t *p_block; |
|---|
| | 229 | void (*pf_release)( picture_t * ); |
|---|
| | 230 | |
|---|
| | 231 | /* Check if we can reuse the current encoder */ |
|---|
| | 232 | if( p_image->p_enc && |
|---|
| | 233 | ( p_image->p_enc->fmt_out.i_codec != p_fmt_out->i_chroma || |
|---|
| | 234 | p_image->p_enc->fmt_out.video.i_width != p_fmt_out->i_width || |
|---|
| | 235 | p_image->p_enc->fmt_out.video.i_height != p_fmt_out->i_height ) ) |
|---|
| | 236 | { |
|---|
| | 237 | DeleteEncoder( p_image->p_enc ); |
|---|
| | 238 | p_image->p_enc = 0; |
|---|
| | 239 | } |
|---|
| | 240 | |
|---|
| | 241 | /* Start an encoder */ |
|---|
| | 242 | if( !p_image->p_enc ) |
|---|
| | 243 | { |
|---|
| | 244 | p_image->p_enc = CreateEncoder( p_image->p_parent, |
|---|
| | 245 | p_fmt_in, p_fmt_out ); |
|---|
| | 246 | if( !p_image->p_enc ) return NULL; |
|---|
| | 247 | } |
|---|
| | 248 | |
|---|
| | 249 | /* Check if we need chroma conversion or resizing */ |
|---|
| | 250 | if( p_image->p_enc->fmt_in.video.i_chroma != p_fmt_in->i_chroma || |
|---|
| | 251 | p_image->p_enc->fmt_in.video.i_width != p_fmt_in->i_width || |
|---|
| | 252 | p_image->p_enc->fmt_in.video.i_height != p_fmt_in->i_height ) |
|---|
| | 253 | { |
|---|
| | 254 | picture_t *p_pif; |
|---|
| | 255 | |
|---|
| | 256 | if( p_image->p_filter ) |
|---|
| | 257 | if( p_image->p_filter->fmt_in.video.i_chroma != p_fmt_in->i_chroma || |
|---|
| | 258 | p_image->p_filter->fmt_out.video.i_chroma != |
|---|
| | 259 | p_image->p_enc->fmt_in.video.i_chroma ) |
|---|
| | 260 | { |
|---|
| | 261 | /* We need to restart a new filter */ |
|---|
| | 262 | DeleteFilter( p_image->p_filter ); |
|---|
| | 263 | p_image->p_filter = 0; |
|---|
| | 264 | } |
|---|
| | 265 | |
|---|
| | 266 | /* Start a filter */ |
|---|
| | 267 | if( !p_image->p_filter ) |
|---|
| | 268 | { |
|---|
| | 269 | es_format_t fmt_in; |
|---|
| | 270 | es_format_Init( &fmt_in, VIDEO_ES, p_fmt_in->i_chroma ); |
|---|
| | 271 | fmt_in.video = *p_fmt_in; |
|---|
| | 272 | |
|---|
| | 273 | p_image->p_filter = |
|---|
| | 274 | CreateFilter( p_image->p_parent, &fmt_in, |
|---|
| | 275 | &p_image->p_enc->fmt_in.video ); |
|---|
| | 276 | |
|---|
| | 277 | if( !p_image->p_filter ) |
|---|
| | 278 | { |
|---|
| | 279 | return NULL; |
|---|
| | 280 | } |
|---|
| | 281 | } |
|---|
| | 282 | else |
|---|
| | 283 | { |
|---|
| | 284 | /* Filters should handle on-the-fly size changes */ |
|---|
| | 285 | p_image->p_filter->fmt_in.i_codec = p_fmt_in->i_chroma; |
|---|
| | 286 | p_image->p_filter->fmt_out.video = *p_fmt_in; |
|---|
| | 287 | p_image->p_filter->fmt_out.i_codec =p_image->p_enc->fmt_in.i_codec; |
|---|
| | 288 | p_image->p_filter->fmt_out.video = p_image->p_enc->fmt_in.video; |
|---|
| | 289 | } |
|---|
| | 290 | |
|---|
| | 291 | pf_release = p_pic->pf_release; |
|---|
| | 292 | p_pic->pf_release = PicRelease; /* Small hack */ |
|---|
| | 293 | p_pif = p_image->p_filter->pf_video_filter( p_image->p_filter, p_pic ); |
|---|
| | 294 | p_pic->pf_release = pf_release; |
|---|
| | 295 | p_pic = p_pif; |
|---|
| | 296 | } |
|---|
| | 297 | |
|---|
| | 298 | p_block = p_image->p_enc->pf_encode_video( p_image->p_enc, p_pic ); |
|---|
| | 299 | |
|---|
| | 300 | if( !p_block ) |
|---|
| | 301 | { |
|---|
| | 302 | msg_Dbg( p_image->p_parent, "no image encoded" ); |
|---|
| | 303 | return 0; |
|---|
| | 304 | } |
|---|
| | 305 | |
|---|
| | 306 | return p_block; |
|---|
| 229 | | return VLC_EGENERIC; |
|---|
| | 313 | block_t *p_block; |
|---|
| | 314 | FILE *file; |
|---|
| | 315 | |
|---|
| | 316 | if( !p_fmt_out->i_chroma ) |
|---|
| | 317 | { |
|---|
| | 318 | /* Try to guess format from file name */ |
|---|
| | 319 | p_fmt_out->i_chroma = Ext2Fourcc( psz_url ); |
|---|
| | 320 | } |
|---|
| | 321 | |
|---|
| | 322 | file = fopen( psz_url, "wb" ); |
|---|
| | 323 | if( !file ) |
|---|
| | 324 | { |
|---|
| | 325 | msg_Dbg( p_image->p_parent, "could not open file %s for writing", |
|---|
| | 326 | psz_url ); |
|---|
| | 327 | return VLC_EGENERIC; |
|---|
| | 328 | } |
|---|
| | 329 | |
|---|
| | 330 | p_block = ImageWrite( p_image, p_pic, p_fmt_in, p_fmt_out ); |
|---|
| | 331 | |
|---|
| | 332 | if( p_block ) |
|---|
| | 333 | { |
|---|
| | 334 | fwrite( p_block->p_buffer, sizeof(char), p_block->i_buffer, file ); |
|---|
| | 335 | block_Release( p_block ); |
|---|
| | 336 | } |
|---|
| | 337 | |
|---|
| | 338 | fclose( file ); |
|---|
| | 339 | |
|---|
| | 340 | return p_block ? VLC_SUCCESS : VLC_EGENERIC; |
|---|
| | 494 | } |
|---|
| | 495 | |
|---|
| | 496 | static encoder_t *CreateEncoder( vlc_object_t *p_this, video_format_t *fmt_in, |
|---|
| | 497 | video_format_t *fmt_out ) |
|---|
| | 498 | { |
|---|
| | 499 | encoder_t *p_enc; |
|---|
| | 500 | |
|---|
| | 501 | p_enc = vlc_object_create( p_this, VLC_OBJECT_ENCODER ); |
|---|
| | 502 | if( p_enc == NULL ) |
|---|
| | 503 | { |
|---|
| | 504 | msg_Err( p_this, "out of memory" ); |
|---|
| | 505 | return NULL; |
|---|
| | 506 | } |
|---|
| | 507 | |
|---|
| | 508 | p_enc->p_module = NULL; |
|---|
| | 509 | es_format_Init( &p_enc->fmt_in, VIDEO_ES, fmt_in->i_chroma ); |
|---|
| | 510 | p_enc->fmt_in.video = *fmt_in; |
|---|
| | 511 | if( fmt_out->i_width > 0 && fmt_out->i_height > 0 ) |
|---|
| | 512 | { |
|---|
| | 513 | p_enc->fmt_in.video.i_width = fmt_out->i_width; |
|---|
| | 514 | p_enc->fmt_in.video.i_height = fmt_out->i_height; |
|---|
| | 515 | } |
|---|
| | 516 | p_enc->fmt_in.video.i_frame_rate = 25; |
|---|
| | 517 | p_enc->fmt_in.video.i_frame_rate_base = 1; |
|---|
| | 518 | |
|---|
| | 519 | es_format_Init( &p_enc->fmt_out, VIDEO_ES, fmt_out->i_chroma ); |
|---|
| | 520 | p_enc->fmt_out.video = *fmt_out; |
|---|
| | 521 | p_enc->fmt_out.video.i_width = p_enc->fmt_in.video.i_width; |
|---|
| | 522 | p_enc->fmt_out.video.i_height = p_enc->fmt_in.video.i_height; |
|---|
| | 523 | |
|---|
| | 524 | vlc_object_attach( p_enc, p_this ); |
|---|
| | 525 | |
|---|
| | 526 | /* Find a suitable decoder module */ |
|---|
| | 527 | p_enc->p_module = module_Need( p_enc, "encoder", 0, 0 ); |
|---|
| | 528 | if( !p_enc->p_module ) |
|---|
| | 529 | { |
|---|
| | 530 | msg_Err( p_enc, "no suitable encoder module for fourcc `%4.4s'.\n" |
|---|
| | 531 | "VLC probably does not support this image format.", |
|---|
| | 532 | (char*)&p_enc->fmt_out.i_codec ); |
|---|
| | 533 | |
|---|
| | 534 | DeleteEncoder( p_enc ); |
|---|
| | 535 | return NULL; |
|---|
| | 536 | } |
|---|
| | 537 | p_enc->fmt_in.video.i_chroma = p_enc->fmt_in.i_codec; |
|---|
| | 538 | |
|---|
| | 539 | return p_enc; |
|---|
| | 540 | } |
|---|
| | 541 | |
|---|
| | 542 | static void DeleteEncoder( encoder_t * p_enc ) |
|---|
| | 543 | { |
|---|
| | 544 | vlc_object_detach( p_enc ); |
|---|
| | 545 | |
|---|
| | 546 | if( p_enc->p_module ) module_Unneed( p_enc, p_enc->p_module ); |
|---|
| | 547 | |
|---|
| | 548 | es_format_Clean( &p_enc->fmt_in ); |
|---|
| | 549 | es_format_Clean( &p_enc->fmt_out ); |
|---|
| | 550 | |
|---|
| | 551 | vlc_object_destroy( p_enc ); |
|---|