1 /*****************************************************************************
2 * video.c: transcoding stream output module (video)
3 *****************************************************************************
4 * Copyright (C) 2003-2009 the VideoLAN team
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8 * Gildas Bazin <gbazin@videolan.org>
9 * Jean-Paul Saman <jpsaman #_at_# m2x dot nl>
10 * Antoine Cellerier <dionoea at videolan dot org>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25 *****************************************************************************/
27 /*****************************************************************************
29 *****************************************************************************/
31 #include "transcode.h"
35 #include <vlc_modules.h>
37 #define ENC_FRAMERATE (25 * 1000 + .5)
38 #define ENC_FRAMERATE_BASE 1000
40 struct decoder_owner_sys_t
42 sout_stream_sys_t *p_sys;
45 static void video_del_buffer_decoder( decoder_t *p_decoder, picture_t *p_pic )
47 VLC_UNUSED(p_decoder);
48 picture_Release( p_pic );
51 static void video_link_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
54 picture_Hold( p_pic );
57 static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
60 picture_Release( p_pic );
63 static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
65 sout_stream_sys_t *p_ssys = p_dec->p_owner->p_sys;
66 if( p_ssys->i_threads >= 1 )
68 int i_first_pic = p_ssys->i_first_pic;
70 if( p_ssys->i_first_pic != p_ssys->i_last_pic )
72 /* Encoder still has stuff to encode, wait to clear-up the list */
73 while( p_ssys->i_first_pic == i_first_pic )
75 #warning THERE IS DEFINITELY A BUG! LOCKING IS INSUFFICIENT!
82 p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
83 return picture_NewFromFormat( &p_dec->fmt_out.video );
86 static picture_t *transcode_video_filter_buffer_new( filter_t *p_filter )
88 p_filter->fmt_out.video.i_chroma = p_filter->fmt_out.i_codec;
89 return picture_NewFromFormat( &p_filter->fmt_out.video );
91 static void transcode_video_filter_buffer_del( filter_t *p_filter, picture_t *p_pic )
94 picture_Release( p_pic );
97 static int transcode_video_filter_allocation_init( filter_t *p_filter,
101 p_filter->pf_video_buffer_new = transcode_video_filter_buffer_new;
102 p_filter->pf_video_buffer_del = transcode_video_filter_buffer_del;
106 static void transcode_video_filter_allocation_clear( filter_t *p_filter )
108 VLC_UNUSED(p_filter);
111 static void* EncoderThread( void *obj )
113 sout_stream_sys_t *p_sys = (sout_stream_sys_t*)obj;
114 sout_stream_id_t *id = p_sys->id_video;
116 int canc = vlc_savecancel ();
122 vlc_mutex_lock( &p_sys->lock_out );
123 while( !p_sys->b_abort && p_sys->i_last_pic == p_sys->i_first_pic )
124 vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );
128 vlc_mutex_unlock( &p_sys->lock_out );
132 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
133 p_sys->i_first_pic %= PICTURE_RING_SIZE;
134 vlc_mutex_unlock( &p_sys->lock_out );
136 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
138 vlc_mutex_lock( &p_sys->lock_out );
139 block_ChainAppend( &p_sys->p_buffers, p_block );
141 vlc_mutex_unlock( &p_sys->lock_out );
142 picture_Release( p_pic );
145 while( p_sys->i_last_pic != p_sys->i_first_pic )
147 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
148 p_sys->i_first_pic %= PICTURE_RING_SIZE;
149 picture_Release( p_pic );
151 block_ChainRelease( p_sys->p_buffers );
153 vlc_restorecancel (canc);
157 int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
159 sout_stream_sys_t *p_sys = p_stream->p_sys;
162 * Initialization of decoder structures
164 id->p_decoder->fmt_out = id->p_decoder->fmt_in;
165 id->p_decoder->fmt_out.i_extra = 0;
166 id->p_decoder->fmt_out.p_extra = 0;
167 id->p_decoder->pf_decode_video = NULL;
168 id->p_decoder->pf_get_cc = NULL;
169 id->p_decoder->pf_get_cc = 0;
170 id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
171 id->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder;
172 id->p_decoder->pf_picture_link = video_link_picture_decoder;
173 id->p_decoder->pf_picture_unlink = video_unlink_picture_decoder;
174 id->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) );
175 if( !id->p_decoder->p_owner )
178 id->p_decoder->p_owner->p_sys = p_sys;
179 /* id->p_decoder->p_cfg = p_sys->p_video_cfg; */
181 id->p_decoder->p_module =
182 module_need( id->p_decoder, "decoder", "$codec", false );
184 if( !id->p_decoder->p_module )
186 msg_Err( p_stream, "cannot find video decoder" );
187 free( id->p_decoder->p_owner );
193 * Because some info about the decoded input will only be available
194 * once the first frame is decoded, we actually only test the availability
195 * of the encoder here.
198 /* Initialization of encoder format structures */
199 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
200 id->p_decoder->fmt_out.i_codec );
201 id->p_encoder->fmt_in.video.i_chroma = id->p_decoder->fmt_out.i_codec;
203 /* The dimensions will be set properly later on.
204 * Just put sensible values so we can test an encoder is available. */
205 id->p_encoder->fmt_in.video.i_width =
206 id->p_encoder->fmt_out.video.i_width
207 ? id->p_encoder->fmt_out.video.i_width
208 : id->p_decoder->fmt_in.video.i_width
209 ? id->p_decoder->fmt_in.video.i_width : 16;
210 id->p_encoder->fmt_in.video.i_height =
211 id->p_encoder->fmt_out.video.i_height
212 ? id->p_encoder->fmt_out.video.i_height
213 : id->p_decoder->fmt_in.video.i_height
214 ? id->p_decoder->fmt_in.video.i_height : 16;
215 id->p_encoder->fmt_in.video.i_frame_rate = ENC_FRAMERATE;
216 id->p_encoder->fmt_in.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
218 id->p_encoder->i_threads = p_sys->i_threads;
219 id->p_encoder->p_cfg = p_sys->p_video_cfg;
221 id->p_encoder->p_module =
222 module_need( id->p_encoder, "encoder", p_sys->psz_venc, true );
223 if( !id->p_encoder->p_module )
225 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s). Take a look few lines earlier to see possible reason.",
226 p_sys->psz_venc ? p_sys->psz_venc : "any",
227 (char *)&p_sys->i_vcodec );
228 module_unneed( id->p_decoder, id->p_decoder->p_module );
229 id->p_decoder->p_module = 0;
230 free( id->p_decoder->p_owner );
234 /* Close the encoder.
235 * We'll open it only when we have the first frame. */
236 module_unneed( id->p_encoder, id->p_encoder->p_module );
237 if( id->p_encoder->fmt_out.p_extra )
239 free( id->p_encoder->fmt_out.p_extra );
240 id->p_encoder->fmt_out.p_extra = NULL;
241 id->p_encoder->fmt_out.i_extra = 0;
243 id->p_encoder->p_module = NULL;
245 if( p_sys->i_threads >= 1 )
247 int i_priority = p_sys->b_high_priority ? VLC_THREAD_PRIORITY_OUTPUT :
248 VLC_THREAD_PRIORITY_VIDEO;
249 p_sys->id_video = id;
250 vlc_mutex_init( &p_sys->lock_out );
251 vlc_cond_init( &p_sys->cond );
252 memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) );
253 p_sys->i_first_pic = 0;
254 p_sys->i_last_pic = 0;
255 p_sys->p_buffers = NULL;
257 if( vlc_clone( &p_sys->thread, EncoderThread, p_sys, i_priority ) )
259 msg_Err( p_stream, "cannot spawn encoder thread" );
260 module_unneed( id->p_decoder, id->p_decoder->p_module );
261 id->p_decoder->p_module = 0;
262 free( id->p_decoder->p_owner );
269 static void transcode_video_filter_init( sout_stream_t *p_stream,
270 sout_stream_id_t *id )
273 id->p_f_chain = filter_chain_New( p_stream, "video filter2",
275 transcode_video_filter_allocation_init,
276 transcode_video_filter_allocation_clear,
279 if( p_stream->p_sys->b_deinterlace )
281 filter_chain_AppendFilter( id->p_f_chain,
282 p_stream->p_sys->psz_deinterlace,
283 p_stream->p_sys->p_deinterlace_cfg,
284 &id->p_decoder->fmt_out,
285 &id->p_decoder->fmt_out );
288 /* Take care of the scaling and chroma conversions */
289 if( ( id->p_decoder->fmt_out.video.i_chroma !=
290 id->p_encoder->fmt_in.video.i_chroma ) ||
291 ( id->p_decoder->fmt_out.video.i_width !=
292 id->p_encoder->fmt_in.video.i_width ) ||
293 ( id->p_decoder->fmt_out.video.i_height !=
294 id->p_encoder->fmt_in.video.i_height ) )
296 filter_chain_AppendFilter( id->p_f_chain,
298 &id->p_decoder->fmt_out,
299 &id->p_encoder->fmt_in );
302 if( p_stream->p_sys->psz_vf2 )
304 const es_format_t *p_fmt_out;
305 id->p_uf_chain = filter_chain_New( p_stream, "video filter2",
307 transcode_video_filter_allocation_init,
308 transcode_video_filter_allocation_clear,
310 filter_chain_Reset( id->p_uf_chain, &id->p_encoder->fmt_in,
311 &id->p_encoder->fmt_in );
312 filter_chain_AppendFromString( id->p_uf_chain, p_stream->p_sys->psz_vf2 );
313 p_fmt_out = filter_chain_GetFmtOut( id->p_uf_chain );
314 es_format_Copy( &id->p_encoder->fmt_in, p_fmt_out );
315 id->p_encoder->fmt_out.video.i_width =
316 id->p_encoder->fmt_in.video.i_width;
317 id->p_encoder->fmt_out.video.i_height =
318 id->p_encoder->fmt_in.video.i_height;
319 id->p_encoder->fmt_out.video.i_sar_num =
320 id->p_encoder->fmt_in.video.i_sar_num;
321 id->p_encoder->fmt_out.video.i_sar_den =
322 id->p_encoder->fmt_in.video.i_sar_den;
327 static void transcode_video_encoder_init( sout_stream_t *p_stream,
328 sout_stream_id_t *id )
330 sout_stream_sys_t *p_sys = p_stream->p_sys;
333 * width/height of source */
334 int i_src_width = id->p_decoder->fmt_out.video.i_width;
335 int i_src_height = id->p_decoder->fmt_out.video.i_height;
337 /* with/height scaling */
338 float f_scale_width = 1;
339 float f_scale_height = 1;
341 /* width/height of output stream */
346 float f_aspect = (double)id->p_decoder->fmt_out.video.i_sar_num *
347 id->p_decoder->fmt_out.video.i_width /
348 id->p_decoder->fmt_out.video.i_sar_den /
349 id->p_decoder->fmt_out.video.i_height;
351 msg_Dbg( p_stream, "decoder aspect is %f:1", f_aspect );
353 /* Change f_aspect from source frame to source pixel */
354 f_aspect = f_aspect * i_src_height / i_src_width;
355 msg_Dbg( p_stream, "source pixel aspect is %f:1", f_aspect );
357 /* Calculate scaling factor for specified parameters */
358 if( id->p_encoder->fmt_out.video.i_width <= 0 &&
359 id->p_encoder->fmt_out.video.i_height <= 0 && p_sys->f_scale )
361 /* Global scaling. Make sure width will remain a factor of 16 */
364 int i_new_width = i_src_width * p_sys->f_scale;
366 if( i_new_width % 16 <= 7 && i_new_width >= 16 )
367 i_new_width -= i_new_width % 16;
369 i_new_width += 16 - i_new_width % 16;
371 f_real_scale = (float)( i_new_width ) / (float) i_src_width;
373 i_new_height = __MAX( 16, i_src_height * (float)f_real_scale );
375 f_scale_width = f_real_scale;
376 f_scale_height = (float) i_new_height / (float) i_src_height;
378 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
379 id->p_encoder->fmt_out.video.i_height <= 0 )
381 /* Only width specified */
382 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
383 f_scale_height = f_scale_width;
385 else if( id->p_encoder->fmt_out.video.i_width <= 0 &&
386 id->p_encoder->fmt_out.video.i_height > 0 )
388 /* Only height specified */
389 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
390 f_scale_width = f_scale_height;
392 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
393 id->p_encoder->fmt_out.video.i_height > 0 )
395 /* Width and height specified */
396 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
397 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
400 /* check maxwidth and maxheight */
401 if( p_sys->i_maxwidth && f_scale_width > (float)p_sys->i_maxwidth /
404 f_scale_width = (float)p_sys->i_maxwidth / i_src_width;
407 if( p_sys->i_maxheight && f_scale_height > (float)p_sys->i_maxheight /
410 f_scale_height = (float)p_sys->i_maxheight / i_src_height;
414 /* Change aspect ratio from source pixel to scaled pixel */
415 f_aspect = f_aspect * f_scale_height / f_scale_width;
416 msg_Dbg( p_stream, "scaled pixel aspect is %f:1", f_aspect );
418 /* f_scale_width and f_scale_height are now final */
419 /* Calculate width, height from scaling
420 * Make sure its multiple of 2
422 i_dst_width = 2 * (int)(f_scale_width*i_src_width/2+0.5);
423 i_dst_height = 2 * (int)(f_scale_height*i_src_height/2+0.5);
425 /* Change aspect ratio from scaled pixel to output frame */
426 f_aspect = f_aspect * i_dst_width / i_dst_height;
428 /* Store calculated values */
429 id->p_encoder->fmt_out.video.i_width =
430 id->p_encoder->fmt_out.video.i_visible_width = i_dst_width;
431 id->p_encoder->fmt_out.video.i_height =
432 id->p_encoder->fmt_out.video.i_visible_height = i_dst_height;
434 id->p_encoder->fmt_in.video.i_width =
435 id->p_encoder->fmt_in.video.i_visible_width = i_dst_width;
436 id->p_encoder->fmt_in.video.i_height =
437 id->p_encoder->fmt_in.video.i_visible_height = i_dst_height;
439 msg_Dbg( p_stream, "source %ix%i, destination %ix%i",
440 i_src_width, i_src_height,
441 i_dst_width, i_dst_height
444 /* Handle frame rate conversion */
445 if( !id->p_encoder->fmt_out.video.i_frame_rate ||
446 !id->p_encoder->fmt_out.video.i_frame_rate_base )
448 if( id->p_decoder->fmt_out.video.i_frame_rate &&
449 id->p_decoder->fmt_out.video.i_frame_rate_base )
451 id->p_encoder->fmt_out.video.i_frame_rate =
452 id->p_decoder->fmt_out.video.i_frame_rate;
453 id->p_encoder->fmt_out.video.i_frame_rate_base =
454 id->p_decoder->fmt_out.video.i_frame_rate_base;
458 /* Pick a sensible default value */
459 id->p_encoder->fmt_out.video.i_frame_rate = ENC_FRAMERATE;
460 id->p_encoder->fmt_out.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
464 id->p_encoder->fmt_in.video.i_frame_rate =
465 id->p_encoder->fmt_out.video.i_frame_rate;
466 id->p_encoder->fmt_in.video.i_frame_rate_base =
467 id->p_encoder->fmt_out.video.i_frame_rate_base;
469 date_Init( &id->interpolated_pts,
470 id->p_encoder->fmt_out.video.i_frame_rate,
471 id->p_encoder->fmt_out.video.i_frame_rate_base );
473 /* Check whether a particular aspect ratio was requested */
474 if( id->p_encoder->fmt_out.video.i_sar_num <= 0 ||
475 id->p_encoder->fmt_out.video.i_sar_den <= 0 )
477 vlc_ureduce( &id->p_encoder->fmt_out.video.i_sar_num,
478 &id->p_encoder->fmt_out.video.i_sar_den,
479 (uint64_t)id->p_decoder->fmt_out.video.i_sar_num * i_src_width * i_dst_height,
480 (uint64_t)id->p_decoder->fmt_out.video.i_sar_den * i_src_height * i_dst_width,
485 vlc_ureduce( &id->p_encoder->fmt_out.video.i_sar_num,
486 &id->p_encoder->fmt_out.video.i_sar_den,
487 id->p_encoder->fmt_out.video.i_sar_num,
488 id->p_encoder->fmt_out.video.i_sar_den,
492 id->p_encoder->fmt_in.video.i_sar_num =
493 id->p_encoder->fmt_out.video.i_sar_num;
494 id->p_encoder->fmt_in.video.i_sar_den =
495 id->p_encoder->fmt_out.video.i_sar_den;
497 msg_Dbg( p_stream, "encoder aspect is %i:%i",
498 id->p_encoder->fmt_out.video.i_sar_num * id->p_encoder->fmt_out.video.i_width,
499 id->p_encoder->fmt_out.video.i_sar_den * id->p_encoder->fmt_out.video.i_height );
501 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
504 static int transcode_video_encoder_open( sout_stream_t *p_stream,
505 sout_stream_id_t *id )
507 sout_stream_sys_t *p_sys = p_stream->p_sys;
510 msg_Dbg( p_stream, "destination (after video filters) %ix%i",
511 id->p_encoder->fmt_in.video.i_width,
512 id->p_encoder->fmt_in.video.i_height );
514 id->p_encoder->p_module =
515 module_need( id->p_encoder, "encoder", p_sys->psz_venc, true );
516 if( !id->p_encoder->p_module )
518 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
519 p_sys->psz_venc ? p_sys->psz_venc : "any",
520 (char *)&p_sys->i_vcodec );
524 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
527 id->p_encoder->fmt_out.i_codec =
528 vlc_fourcc_GetCodec( VIDEO_ES, id->p_encoder->fmt_out.i_codec );
530 id->id = sout_StreamIdAdd( p_stream->p_next, &id->p_encoder->fmt_out );
533 msg_Err( p_stream, "cannot add this stream" );
540 void transcode_video_close( sout_stream_t *p_stream,
541 sout_stream_id_t *id )
543 if( p_stream->p_sys->i_threads >= 1 )
545 vlc_mutex_lock( &p_stream->p_sys->lock_out );
546 p_stream->p_sys->b_abort = true;
547 vlc_cond_signal( &p_stream->p_sys->cond );
548 vlc_mutex_unlock( &p_stream->p_sys->lock_out );
550 vlc_join( p_stream->p_sys->thread, NULL );
551 vlc_mutex_destroy( &p_stream->p_sys->lock_out );
552 vlc_cond_destroy( &p_stream->p_sys->cond );
556 if( id->p_decoder->p_module )
557 module_unneed( id->p_decoder, id->p_decoder->p_module );
558 if( id->p_decoder->p_description )
559 vlc_meta_Delete( id->p_decoder->p_description );
561 free( id->p_decoder->p_owner );
564 if( id->p_encoder->p_module )
565 module_unneed( id->p_encoder, id->p_encoder->p_module );
569 filter_chain_Delete( id->p_f_chain );
571 filter_chain_Delete( id->p_uf_chain );
574 int transcode_video_process( sout_stream_t *p_stream, sout_stream_id_t *id,
575 block_t *in, block_t **out )
577 sout_stream_sys_t *p_sys = p_stream->p_sys;
578 bool b_need_duplicate = false;
579 picture_t *p_pic, *p_pic2 = NULL;
584 if( p_sys->i_threads == 0 )
588 p_block = id->p_encoder->pf_encode_video(id->p_encoder, NULL );
589 block_ChainAppend( out, p_block );
595 * FIXME: we need EncoderThread() to flush buffers and signal us
596 * when it's done so we can send the last frames to the chain
603 while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
606 if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )
608 mtime_t current_date = mdate();
609 if( current_date + 50000 > p_pic->date )
611 msg_Dbg( p_stream, "late picture skipped (%"PRId64")",
612 current_date + 50000 - p_pic->date );
613 picture_Release( p_pic );
618 if( p_sys->b_master_sync )
620 mtime_t i_video_drift;
621 mtime_t i_master_drift = p_sys->i_master_drift;
624 i_pts = date_Get( &id->interpolated_pts ) + 1;
625 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
626 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
628 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
629 date_Set( &id->interpolated_pts, p_pic->date );
630 i_pts = p_pic->date + 1;
632 i_video_drift = p_pic->date - i_pts;
633 b_need_duplicate = false;
635 /* Set the pts of the frame being encoded */
638 if( i_video_drift < (i_master_drift - 50000) )
641 msg_Dbg( p_stream, "dropping frame (%i)",
642 (int)(i_video_drift - i_master_drift) );
644 picture_Release( p_pic );
647 else if( i_video_drift > (i_master_drift + 50000) )
650 msg_Dbg( p_stream, "adding frame (%i)",
651 (int)(i_video_drift - i_master_drift) );
653 b_need_duplicate = true;
657 if( unlikely( !id->p_encoder->p_module ) )
659 transcode_video_encoder_init( p_stream, id );
661 transcode_video_filter_init( p_stream, id );
663 if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS )
665 picture_Release( p_pic );
666 transcode_video_close( p_stream, id );
667 id->b_transcode = false;
672 /* Run filter chain */
674 p_pic = filter_chain_VideoFilter( id->p_f_chain, p_pic );
680 /* Check if we have a subpicture to overlay */
683 video_format_t fmt = id->p_encoder->fmt_in.video;
684 if( fmt.i_visible_width <= 0 || fmt.i_visible_height <= 0 )
686 fmt.i_visible_width = fmt.i_width;
687 fmt.i_visible_height = fmt.i_height;
692 subpicture_t *p_subpic = spu_Render( p_sys->p_spu, NULL, &fmt, &fmt,
693 p_pic->date, p_pic->date, false );
695 /* Overlay subpicture */
698 if( picture_IsReferenced( p_pic ) && !filter_chain_GetLength( id->p_f_chain ) )
700 /* We can't modify the picture, we need to duplicate it */
701 picture_t *p_tmp = video_new_buffer_decoder( id->p_decoder );
704 picture_Copy( p_tmp, p_pic );
705 picture_Release( p_pic );
709 if( !p_sys->p_spu_blend )
710 p_sys->p_spu_blend = filter_NewBlend( VLC_OBJECT( p_sys->p_spu ), &fmt );
711 if( p_sys->p_spu_blend )
712 picture_BlendSubpicture( p_pic, p_sys->p_spu_blend, p_subpic );
713 subpicture_Delete( p_subpic );
717 /* Run user specified filter chain */
719 p_pic = filter_chain_VideoFilter( id->p_uf_chain, p_pic );
721 if( p_sys->i_threads == 0 )
725 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
726 block_ChainAppend( out, p_block );
729 if( p_sys->b_master_sync )
731 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
732 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
733 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
735 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
736 date_Set( &id->interpolated_pts, p_pic->date );
737 i_pts = p_pic->date + 1;
739 date_Increment( &id->interpolated_pts, 1 );
741 if( unlikely( b_need_duplicate ) )
744 if( p_sys->i_threads >= 1 )
746 /* We can't modify the picture, we need to duplicate it */
747 p_pic2 = video_new_buffer_decoder( id->p_decoder );
750 picture_Copy( p_pic2, p_pic );
751 p_pic2->date = i_pts;
758 p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);
759 block_ChainAppend( out, p_block );
764 if( p_sys->i_threads == 0 )
766 picture_Release( p_pic );
770 vlc_mutex_lock( &p_sys->lock_out );
771 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
772 p_sys->i_last_pic %= PICTURE_RING_SIZE;
773 *out = p_sys->p_buffers;
774 p_sys->p_buffers = NULL;
777 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic2;
778 p_sys->i_last_pic %= PICTURE_RING_SIZE;
780 vlc_cond_signal( &p_sys->cond );
781 vlc_mutex_unlock( &p_sys->lock_out );
788 bool transcode_video_add( sout_stream_t *p_stream, es_format_t *p_fmt,
789 sout_stream_id_t *id )
791 sout_stream_sys_t *p_sys = p_stream->p_sys;
794 "creating video transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
795 (char*)&p_fmt->i_codec, (char*)&p_sys->i_vcodec );
797 /* Complete destination format */
798 id->p_encoder->fmt_out.i_codec = p_sys->i_vcodec;
799 id->p_encoder->fmt_out.video.i_width = p_sys->i_width & ~1;
800 id->p_encoder->fmt_out.video.i_height = p_sys->i_height & ~1;
801 id->p_encoder->fmt_out.i_bitrate = p_sys->i_vbitrate;
803 /* Build decoder -> filter -> encoder chain */
804 if( transcode_video_new( p_stream, id ) )
806 msg_Err( p_stream, "cannot create video chain" );
810 /* Stream will be added later on because we don't know
811 * all the characteristics of the decoded stream yet */
812 id->b_transcode = true;
814 if( p_sys->f_fps > 0 )
816 id->p_encoder->fmt_out.video.i_frame_rate = (p_sys->f_fps * 1000) + 0.5;
817 id->p_encoder->fmt_out.video.i_frame_rate_base = ENC_FRAMERATE_BASE;