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 inline void video_timer_start( encoder_t
* p_encoder
)
47 stats_TimerStart( p_encoder
, "encoding video frame",
48 STATS_TIMER_VIDEO_FRAME_ENCODING
);
51 static inline void video_timer_stop( encoder_t
* p_encoder
)
53 stats_TimerStop( p_encoder
, STATS_TIMER_VIDEO_FRAME_ENCODING
);
56 static inline void video_timer_close( encoder_t
* p_encoder
)
58 stats_TimerDump( p_encoder
, STATS_TIMER_VIDEO_FRAME_ENCODING
);
59 stats_TimerClean( p_encoder
, STATS_TIMER_VIDEO_FRAME_ENCODING
);
62 static void video_del_buffer_decoder( decoder_t
*p_decoder
, picture_t
*p_pic
)
64 VLC_UNUSED(p_decoder
);
65 picture_Release( p_pic
);
68 static void video_link_picture_decoder( decoder_t
*p_dec
, picture_t
*p_pic
)
71 picture_Hold( p_pic
);
74 static void video_unlink_picture_decoder( decoder_t
*p_dec
, picture_t
*p_pic
)
77 picture_Release( p_pic
);
80 static picture_t
*video_new_buffer_decoder( decoder_t
*p_dec
)
82 sout_stream_sys_t
*p_ssys
= p_dec
->p_owner
->p_sys
;
83 if( p_ssys
->i_threads
>= 1 )
85 int i_first_pic
= p_ssys
->i_first_pic
;
87 if( p_ssys
->i_first_pic
!= p_ssys
->i_last_pic
)
89 /* Encoder still has stuff to encode, wait to clear-up the list */
90 while( p_ssys
->i_first_pic
== i_first_pic
)
92 #warning THERE IS DEFINITELY A BUG! LOCKING IS INSUFFICIENT!
99 p_dec
->fmt_out
.video
.i_chroma
= p_dec
->fmt_out
.i_codec
;
100 return picture_NewFromFormat( &p_dec
->fmt_out
.video
);
103 static picture_t
*transcode_video_filter_buffer_new( filter_t
*p_filter
)
105 p_filter
->fmt_out
.video
.i_chroma
= p_filter
->fmt_out
.i_codec
;
106 return picture_NewFromFormat( &p_filter
->fmt_out
.video
);
108 static void transcode_video_filter_buffer_del( filter_t
*p_filter
, picture_t
*p_pic
)
110 VLC_UNUSED(p_filter
);
111 picture_Release( p_pic
);
114 static int transcode_video_filter_allocation_init( filter_t
*p_filter
,
118 p_filter
->pf_video_buffer_new
= transcode_video_filter_buffer_new
;
119 p_filter
->pf_video_buffer_del
= transcode_video_filter_buffer_del
;
123 static void transcode_video_filter_allocation_clear( filter_t
*p_filter
)
125 VLC_UNUSED(p_filter
);
128 static void* EncoderThread( vlc_object_t
* p_this
)
130 sout_stream_sys_t
*p_sys
= (sout_stream_sys_t
*)p_this
;
131 sout_stream_id_t
*id
= p_sys
->id_video
;
133 int canc
= vlc_savecancel ();
135 while( vlc_object_alive (p_sys
) )
139 vlc_mutex_lock( &p_sys
->lock_out
);
140 while( p_sys
->i_last_pic
== p_sys
->i_first_pic
)
142 vlc_cond_wait( &p_sys
->cond
, &p_sys
->lock_out
);
143 if( !vlc_object_alive (p_sys
) ) break;
145 if( !vlc_object_alive (p_sys
) )
147 vlc_mutex_unlock( &p_sys
->lock_out
);
151 p_pic
= p_sys
->pp_pics
[p_sys
->i_first_pic
++];
152 p_sys
->i_first_pic
%= PICTURE_RING_SIZE
;
153 vlc_mutex_unlock( &p_sys
->lock_out
);
155 video_timer_start( id
->p_encoder
);
156 p_block
= id
->p_encoder
->pf_encode_video( id
->p_encoder
, p_pic
);
157 video_timer_stop( id
->p_encoder
);
159 vlc_mutex_lock( &p_sys
->lock_out
);
160 block_ChainAppend( &p_sys
->p_buffers
, p_block
);
162 vlc_mutex_unlock( &p_sys
->lock_out
);
163 picture_Release( p_pic
);
166 while( p_sys
->i_last_pic
!= p_sys
->i_first_pic
)
168 p_pic
= p_sys
->pp_pics
[p_sys
->i_first_pic
++];
169 p_sys
->i_first_pic
%= PICTURE_RING_SIZE
;
170 picture_Release( p_pic
);
172 block_ChainRelease( p_sys
->p_buffers
);
174 vlc_restorecancel (canc
);
178 int transcode_video_new( sout_stream_t
*p_stream
, sout_stream_id_t
*id
)
180 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
183 * Initialization of decoder structures
185 id
->p_decoder
->fmt_out
= id
->p_decoder
->fmt_in
;
186 id
->p_decoder
->fmt_out
.i_extra
= 0;
187 id
->p_decoder
->fmt_out
.p_extra
= 0;
188 id
->p_decoder
->pf_decode_video
= NULL
;
189 id
->p_decoder
->pf_get_cc
= NULL
;
190 id
->p_decoder
->pf_get_cc
= 0;
191 id
->p_decoder
->pf_vout_buffer_new
= video_new_buffer_decoder
;
192 id
->p_decoder
->pf_vout_buffer_del
= video_del_buffer_decoder
;
193 id
->p_decoder
->pf_picture_link
= video_link_picture_decoder
;
194 id
->p_decoder
->pf_picture_unlink
= video_unlink_picture_decoder
;
195 id
->p_decoder
->p_owner
= malloc( sizeof(decoder_owner_sys_t
) );
196 if( !id
->p_decoder
->p_owner
)
199 id
->p_decoder
->p_owner
->p_sys
= p_sys
;
200 /* id->p_decoder->p_cfg = p_sys->p_video_cfg; */
202 id
->p_decoder
->p_module
=
203 module_need( id
->p_decoder
, "decoder", "$codec", false );
205 if( !id
->p_decoder
->p_module
)
207 msg_Err( p_stream
, "cannot find video decoder" );
208 free( id
->p_decoder
->p_owner
);
214 * Because some info about the decoded input will only be available
215 * once the first frame is decoded, we actually only test the availability
216 * of the encoder here.
219 /* Initialization of encoder format structures */
220 es_format_Init( &id
->p_encoder
->fmt_in
, id
->p_decoder
->fmt_in
.i_cat
,
221 id
->p_decoder
->fmt_out
.i_codec
);
222 id
->p_encoder
->fmt_in
.video
.i_chroma
= id
->p_decoder
->fmt_out
.i_codec
;
224 /* The dimensions will be set properly later on.
225 * Just put sensible values so we can test an encoder is available. */
226 id
->p_encoder
->fmt_in
.video
.i_width
=
227 id
->p_encoder
->fmt_out
.video
.i_width
228 ? id
->p_encoder
->fmt_out
.video
.i_width
229 : id
->p_decoder
->fmt_in
.video
.i_width
230 ? id
->p_decoder
->fmt_in
.video
.i_width
: 16;
231 id
->p_encoder
->fmt_in
.video
.i_height
=
232 id
->p_encoder
->fmt_out
.video
.i_height
233 ? id
->p_encoder
->fmt_out
.video
.i_height
234 : id
->p_decoder
->fmt_in
.video
.i_height
235 ? id
->p_decoder
->fmt_in
.video
.i_height
: 16;
236 id
->p_encoder
->fmt_in
.video
.i_frame_rate
= ENC_FRAMERATE
;
237 id
->p_encoder
->fmt_in
.video
.i_frame_rate_base
= ENC_FRAMERATE_BASE
;
239 id
->p_encoder
->i_threads
= p_sys
->i_threads
;
240 id
->p_encoder
->p_cfg
= p_sys
->p_video_cfg
;
242 id
->p_encoder
->p_module
=
243 module_need( id
->p_encoder
, "encoder", p_sys
->psz_venc
, true );
244 if( !id
->p_encoder
->p_module
)
246 msg_Err( p_stream
, "cannot find video encoder (module:%s fourcc:%4.4s). Take a look few lines earlier to see possible reason.",
247 p_sys
->psz_venc
? p_sys
->psz_venc
: "any",
248 (char *)&p_sys
->i_vcodec
);
249 module_unneed( id
->p_decoder
, id
->p_decoder
->p_module
);
250 id
->p_decoder
->p_module
= 0;
251 free( id
->p_decoder
->p_owner
);
255 /* Close the encoder.
256 * We'll open it only when we have the first frame. */
257 module_unneed( id
->p_encoder
, id
->p_encoder
->p_module
);
258 if( id
->p_encoder
->fmt_out
.p_extra
)
260 free( id
->p_encoder
->fmt_out
.p_extra
);
261 id
->p_encoder
->fmt_out
.p_extra
= NULL
;
262 id
->p_encoder
->fmt_out
.i_extra
= 0;
264 id
->p_encoder
->p_module
= NULL
;
266 if( p_sys
->i_threads
>= 1 )
268 int i_priority
= p_sys
->b_high_priority
? VLC_THREAD_PRIORITY_OUTPUT
:
269 VLC_THREAD_PRIORITY_VIDEO
;
270 p_sys
->id_video
= id
;
271 vlc_mutex_init( &p_sys
->lock_out
);
272 vlc_cond_init( &p_sys
->cond
);
273 memset( p_sys
->pp_pics
, 0, sizeof(p_sys
->pp_pics
) );
274 p_sys
->i_first_pic
= 0;
275 p_sys
->i_last_pic
= 0;
276 p_sys
->p_buffers
= NULL
;
278 if( vlc_thread_create( p_sys
, EncoderThread
, i_priority
) )
280 msg_Err( p_stream
, "cannot spawn encoder thread" );
281 module_unneed( id
->p_decoder
, id
->p_decoder
->p_module
);
282 id
->p_decoder
->p_module
= 0;
283 free( id
->p_decoder
->p_owner
);
290 static void transcode_video_filter_init( sout_stream_t
*p_stream
,
291 sout_stream_id_t
*id
)
294 id
->p_f_chain
= filter_chain_New( p_stream
, "video filter2",
296 transcode_video_filter_allocation_init
,
297 transcode_video_filter_allocation_clear
,
300 if( p_stream
->p_sys
->b_deinterlace
)
302 filter_chain_AppendFilter( id
->p_f_chain
,
303 p_stream
->p_sys
->psz_deinterlace
,
304 p_stream
->p_sys
->p_deinterlace_cfg
,
305 &id
->p_decoder
->fmt_out
,
306 &id
->p_decoder
->fmt_out
);
309 /* Take care of the scaling and chroma conversions */
310 if( ( id
->p_decoder
->fmt_out
.video
.i_chroma
!=
311 id
->p_encoder
->fmt_in
.video
.i_chroma
) ||
312 ( id
->p_decoder
->fmt_out
.video
.i_width
!=
313 id
->p_encoder
->fmt_in
.video
.i_width
) ||
314 ( id
->p_decoder
->fmt_out
.video
.i_height
!=
315 id
->p_encoder
->fmt_in
.video
.i_height
) )
317 filter_chain_AppendFilter( id
->p_f_chain
,
319 &id
->p_decoder
->fmt_out
,
320 &id
->p_encoder
->fmt_in
);
323 if( p_stream
->p_sys
->psz_vf2
)
325 const es_format_t
*p_fmt_out
;
326 id
->p_uf_chain
= filter_chain_New( p_stream
, "video filter2",
328 transcode_video_filter_allocation_init
,
329 transcode_video_filter_allocation_clear
,
331 filter_chain_Reset( id
->p_uf_chain
, &id
->p_encoder
->fmt_in
,
332 &id
->p_encoder
->fmt_in
);
333 filter_chain_AppendFromString( id
->p_uf_chain
, p_stream
->p_sys
->psz_vf2
);
334 p_fmt_out
= filter_chain_GetFmtOut( id
->p_uf_chain
);
335 es_format_Copy( &id
->p_encoder
->fmt_in
, p_fmt_out
);
336 id
->p_encoder
->fmt_out
.video
.i_width
=
337 id
->p_encoder
->fmt_in
.video
.i_width
;
338 id
->p_encoder
->fmt_out
.video
.i_height
=
339 id
->p_encoder
->fmt_in
.video
.i_height
;
340 id
->p_encoder
->fmt_out
.video
.i_sar_num
=
341 id
->p_encoder
->fmt_in
.video
.i_sar_num
;
342 id
->p_encoder
->fmt_out
.video
.i_sar_den
=
343 id
->p_encoder
->fmt_in
.video
.i_sar_den
;
348 static void transcode_video_encoder_init( sout_stream_t
*p_stream
,
349 sout_stream_id_t
*id
)
351 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
354 * width/height of source */
355 int i_src_width
= id
->p_decoder
->fmt_out
.video
.i_width
;
356 int i_src_height
= id
->p_decoder
->fmt_out
.video
.i_height
;
358 /* with/height scaling */
359 float f_scale_width
= 1;
360 float f_scale_height
= 1;
362 /* width/height of output stream */
367 float f_aspect
= (double)id
->p_decoder
->fmt_out
.video
.i_sar_num
*
368 id
->p_decoder
->fmt_out
.video
.i_width
/
369 id
->p_decoder
->fmt_out
.video
.i_sar_den
/
370 id
->p_decoder
->fmt_out
.video
.i_height
;
372 msg_Dbg( p_stream
, "decoder aspect is %f:1", f_aspect
);
374 /* Change f_aspect from source frame to source pixel */
375 f_aspect
= f_aspect
* i_src_height
/ i_src_width
;
376 msg_Dbg( p_stream
, "source pixel aspect is %f:1", f_aspect
);
378 /* Calculate scaling factor for specified parameters */
379 if( id
->p_encoder
->fmt_out
.video
.i_width
<= 0 &&
380 id
->p_encoder
->fmt_out
.video
.i_height
<= 0 && p_sys
->f_scale
)
382 /* Global scaling. Make sure width will remain a factor of 16 */
385 int i_new_width
= i_src_width
* p_sys
->f_scale
;
387 if( i_new_width
% 16 <= 7 && i_new_width
>= 16 )
388 i_new_width
-= i_new_width
% 16;
390 i_new_width
+= 16 - i_new_width
% 16;
392 f_real_scale
= (float)( i_new_width
) / (float) i_src_width
;
394 i_new_height
= __MAX( 16, i_src_height
* (float)f_real_scale
);
396 f_scale_width
= f_real_scale
;
397 f_scale_height
= (float) i_new_height
/ (float) i_src_height
;
399 else if( id
->p_encoder
->fmt_out
.video
.i_width
> 0 &&
400 id
->p_encoder
->fmt_out
.video
.i_height
<= 0 )
402 /* Only width specified */
403 f_scale_width
= (float)id
->p_encoder
->fmt_out
.video
.i_width
/i_src_width
;
404 f_scale_height
= f_scale_width
;
406 else if( id
->p_encoder
->fmt_out
.video
.i_width
<= 0 &&
407 id
->p_encoder
->fmt_out
.video
.i_height
> 0 )
409 /* Only height specified */
410 f_scale_height
= (float)id
->p_encoder
->fmt_out
.video
.i_height
/i_src_height
;
411 f_scale_width
= f_scale_height
;
413 else if( id
->p_encoder
->fmt_out
.video
.i_width
> 0 &&
414 id
->p_encoder
->fmt_out
.video
.i_height
> 0 )
416 /* Width and height specified */
417 f_scale_width
= (float)id
->p_encoder
->fmt_out
.video
.i_width
/i_src_width
;
418 f_scale_height
= (float)id
->p_encoder
->fmt_out
.video
.i_height
/i_src_height
;
421 /* check maxwidth and maxheight */
422 if( p_sys
->i_maxwidth
&& f_scale_width
> (float)p_sys
->i_maxwidth
/
425 f_scale_width
= (float)p_sys
->i_maxwidth
/ i_src_width
;
428 if( p_sys
->i_maxheight
&& f_scale_height
> (float)p_sys
->i_maxheight
/
431 f_scale_height
= (float)p_sys
->i_maxheight
/ i_src_height
;
435 /* Change aspect ratio from source pixel to scaled pixel */
436 f_aspect
= f_aspect
* f_scale_height
/ f_scale_width
;
437 msg_Dbg( p_stream
, "scaled pixel aspect is %f:1", f_aspect
);
439 /* f_scale_width and f_scale_height are now final */
440 /* Calculate width, height from scaling
441 * Make sure its multiple of 2
443 i_dst_width
= 2 * (int)(f_scale_width
*i_src_width
/2+0.5);
444 i_dst_height
= 2 * (int)(f_scale_height
*i_src_height
/2+0.5);
446 /* Change aspect ratio from scaled pixel to output frame */
447 f_aspect
= f_aspect
* i_dst_width
/ i_dst_height
;
449 /* Store calculated values */
450 id
->p_encoder
->fmt_out
.video
.i_width
=
451 id
->p_encoder
->fmt_out
.video
.i_visible_width
= i_dst_width
;
452 id
->p_encoder
->fmt_out
.video
.i_height
=
453 id
->p_encoder
->fmt_out
.video
.i_visible_height
= i_dst_height
;
455 id
->p_encoder
->fmt_in
.video
.i_width
=
456 id
->p_encoder
->fmt_in
.video
.i_visible_width
= i_dst_width
;
457 id
->p_encoder
->fmt_in
.video
.i_height
=
458 id
->p_encoder
->fmt_in
.video
.i_visible_height
= i_dst_height
;
460 msg_Dbg( p_stream
, "source %ix%i, destination %ix%i",
461 i_src_width
, i_src_height
,
462 i_dst_width
, i_dst_height
465 /* Handle frame rate conversion */
466 if( !id
->p_encoder
->fmt_out
.video
.i_frame_rate
||
467 !id
->p_encoder
->fmt_out
.video
.i_frame_rate_base
)
469 if( id
->p_decoder
->fmt_out
.video
.i_frame_rate
&&
470 id
->p_decoder
->fmt_out
.video
.i_frame_rate_base
)
472 id
->p_encoder
->fmt_out
.video
.i_frame_rate
=
473 id
->p_decoder
->fmt_out
.video
.i_frame_rate
;
474 id
->p_encoder
->fmt_out
.video
.i_frame_rate_base
=
475 id
->p_decoder
->fmt_out
.video
.i_frame_rate_base
;
479 /* Pick a sensible default value */
480 id
->p_encoder
->fmt_out
.video
.i_frame_rate
= ENC_FRAMERATE
;
481 id
->p_encoder
->fmt_out
.video
.i_frame_rate_base
= ENC_FRAMERATE_BASE
;
485 id
->p_encoder
->fmt_in
.video
.i_frame_rate
=
486 id
->p_encoder
->fmt_out
.video
.i_frame_rate
;
487 id
->p_encoder
->fmt_in
.video
.i_frame_rate_base
=
488 id
->p_encoder
->fmt_out
.video
.i_frame_rate_base
;
490 date_Init( &id
->interpolated_pts
,
491 id
->p_encoder
->fmt_out
.video
.i_frame_rate
,
492 id
->p_encoder
->fmt_out
.video
.i_frame_rate_base
);
494 /* Check whether a particular aspect ratio was requested */
495 if( id
->p_encoder
->fmt_out
.video
.i_sar_num
<= 0 ||
496 id
->p_encoder
->fmt_out
.video
.i_sar_den
<= 0 )
498 vlc_ureduce( &id
->p_decoder
->fmt_out
.video
.i_sar_num
,
499 &id
->p_decoder
->fmt_out
.video
.i_sar_den
,
500 id
->p_decoder
->fmt_out
.video
.i_sar_num
,
501 id
->p_decoder
->fmt_out
.video
.i_sar_den
,
504 id
->p_encoder
->fmt_out
.video
.i_sar_num
= id
->p_decoder
->fmt_out
.video
.i_sar_num
* i_src_width
/ i_dst_width
;
505 id
->p_encoder
->fmt_out
.video
.i_sar_den
= id
->p_decoder
->fmt_out
.video
.i_sar_den
* i_src_height
/ i_dst_height
;
507 vlc_ureduce( &id
->p_encoder
->fmt_out
.video
.i_sar_num
,
508 &id
->p_encoder
->fmt_out
.video
.i_sar_den
,
509 id
->p_encoder
->fmt_out
.video
.i_sar_num
,
510 id
->p_encoder
->fmt_out
.video
.i_sar_den
,
513 id
->p_encoder
->fmt_in
.video
.i_sar_num
=
514 id
->p_encoder
->fmt_out
.video
.i_sar_num
;
515 id
->p_encoder
->fmt_in
.video
.i_sar_den
=
516 id
->p_encoder
->fmt_out
.video
.i_sar_den
;
518 msg_Dbg( p_stream
, "encoder aspect is %i:%i",
519 id
->p_encoder
->fmt_out
.video
.i_sar_num
* id
->p_encoder
->fmt_out
.video
.i_width
,
520 id
->p_encoder
->fmt_out
.video
.i_sar_den
* id
->p_encoder
->fmt_out
.video
.i_height
);
522 id
->p_encoder
->fmt_in
.video
.i_chroma
= id
->p_encoder
->fmt_in
.i_codec
;
525 static int transcode_video_encoder_open( sout_stream_t
*p_stream
,
526 sout_stream_id_t
*id
)
528 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
531 msg_Dbg( p_stream
, "destination (after video filters) %ix%i",
532 id
->p_encoder
->fmt_in
.video
.i_width
,
533 id
->p_encoder
->fmt_in
.video
.i_height
);
535 id
->p_encoder
->p_module
=
536 module_need( id
->p_encoder
, "encoder", p_sys
->psz_venc
, true );
537 if( !id
->p_encoder
->p_module
)
539 msg_Err( p_stream
, "cannot find video encoder (module:%s fourcc:%4.4s)",
540 p_sys
->psz_venc
? p_sys
->psz_venc
: "any",
541 (char *)&p_sys
->i_vcodec
);
545 id
->p_encoder
->fmt_in
.video
.i_chroma
= id
->p_encoder
->fmt_in
.i_codec
;
548 id
->p_encoder
->fmt_out
.i_codec
=
549 vlc_fourcc_GetCodec( VIDEO_ES
, id
->p_encoder
->fmt_out
.i_codec
);
551 id
->id
= sout_StreamIdAdd( p_stream
->p_next
, &id
->p_encoder
->fmt_out
);
554 msg_Err( p_stream
, "cannot add this stream" );
561 void transcode_video_close( sout_stream_t
*p_stream
,
562 sout_stream_id_t
*id
)
564 if( p_stream
->p_sys
->i_threads
>= 1 )
566 vlc_mutex_lock( &p_stream
->p_sys
->lock_out
);
567 vlc_object_kill( p_stream
->p_sys
);
568 vlc_cond_signal( &p_stream
->p_sys
->cond
);
569 vlc_mutex_unlock( &p_stream
->p_sys
->lock_out
);
570 vlc_thread_join( p_stream
->p_sys
);
571 vlc_mutex_destroy( &p_stream
->p_sys
->lock_out
);
572 vlc_cond_destroy( &p_stream
->p_sys
->cond
);
575 video_timer_close( id
->p_encoder
);
578 if( id
->p_decoder
->p_module
)
579 module_unneed( id
->p_decoder
, id
->p_decoder
->p_module
);
580 if( id
->p_decoder
->p_description
)
581 vlc_meta_Delete( id
->p_decoder
->p_description
);
583 free( id
->p_decoder
->p_owner
);
586 if( id
->p_encoder
->p_module
)
587 module_unneed( id
->p_encoder
, id
->p_encoder
->p_module
);
591 filter_chain_Delete( id
->p_f_chain
);
593 filter_chain_Delete( id
->p_uf_chain
);
596 int transcode_video_process( sout_stream_t
*p_stream
, sout_stream_id_t
*id
,
597 block_t
*in
, block_t
**out
)
599 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
600 bool b_need_duplicate
= false;
601 picture_t
*p_pic
, *p_pic2
= NULL
;
606 if( p_sys
->i_threads
== 0 )
610 video_timer_start( id
->p_encoder
);
611 p_block
= id
->p_encoder
->pf_encode_video(id
->p_encoder
, NULL
);
612 video_timer_stop( id
->p_encoder
);
613 block_ChainAppend( out
, p_block
);
619 * FIXME: we need EncoderThread() to flush buffers and signal us
620 * when it's done so we can send the last frames to the chain
627 while( (p_pic
= id
->p_decoder
->pf_decode_video( id
->p_decoder
, &in
)) )
630 if( p_stream
->p_sout
->i_out_pace_nocontrol
&& p_sys
->b_hurry_up
)
632 mtime_t current_date
= mdate();
633 if( current_date
+ 50000 > p_pic
->date
)
635 msg_Dbg( p_stream
, "late picture skipped (%"PRId64
")",
636 current_date
+ 50000 - p_pic
->date
);
637 picture_Release( p_pic
);
642 if( p_sys
->b_master_sync
)
644 mtime_t i_video_drift
;
645 mtime_t i_master_drift
= p_sys
->i_master_drift
;
648 i_pts
= date_Get( &id
->interpolated_pts
) + 1;
649 if ( p_pic
->date
- i_pts
> MASTER_SYNC_MAX_DRIFT
650 || p_pic
->date
- i_pts
< -MASTER_SYNC_MAX_DRIFT
)
652 msg_Dbg( p_stream
, "drift is too high, resetting master sync" );
653 date_Set( &id
->interpolated_pts
, p_pic
->date
);
654 i_pts
= p_pic
->date
+ 1;
656 i_video_drift
= p_pic
->date
- i_pts
;
657 b_need_duplicate
= false;
659 /* Set the pts of the frame being encoded */
662 if( i_video_drift
< (i_master_drift
- 50000) )
665 msg_Dbg( p_stream
, "dropping frame (%i)",
666 (int)(i_video_drift
- i_master_drift
) );
668 picture_Release( p_pic
);
671 else if( i_video_drift
> (i_master_drift
+ 50000) )
674 msg_Dbg( p_stream
, "adding frame (%i)",
675 (int)(i_video_drift
- i_master_drift
) );
677 b_need_duplicate
= true;
681 if( unlikely( !id
->p_encoder
->p_module
) )
683 transcode_video_encoder_init( p_stream
, id
);
685 transcode_video_filter_init( p_stream
, id
);
687 if( transcode_video_encoder_open( p_stream
, id
) != VLC_SUCCESS
)
689 picture_Release( p_pic
);
690 transcode_video_close( p_stream
, id
);
691 id
->b_transcode
= false;
696 /* Run filter chain */
698 p_pic
= filter_chain_VideoFilter( id
->p_f_chain
, p_pic
);
704 /* Check if we have a subpicture to overlay */
708 if( filter_chain_GetLength( id
->p_f_chain
) > 0 )
709 fmt
= filter_chain_GetFmtOut( id
->p_f_chain
)->video
;
711 fmt
= id
->p_decoder
->fmt_out
.video
;
713 subpicture_t
*p_subpic
= spu_Render( p_sys
->p_spu
, NULL
, &fmt
, &fmt
,
714 p_pic
->date
, p_pic
->date
, false );
716 /* Overlay subpicture */
719 if( picture_IsReferenced( p_pic
) && !filter_chain_GetLength( id
->p_f_chain
) )
721 /* We can't modify the picture, we need to duplicate it */
722 picture_t
*p_tmp
= video_new_buffer_decoder( id
->p_decoder
);
725 picture_Copy( p_tmp
, p_pic
);
726 picture_Release( p_pic
);
730 if( !p_sys
->p_spu_blend
)
731 p_sys
->p_spu_blend
= filter_NewBlend( VLC_OBJECT( p_sys
->p_spu
), &fmt
);
732 if( p_sys
->p_spu_blend
)
733 picture_BlendSubpicture( p_pic
, p_sys
->p_spu_blend
, p_subpic
);
734 subpicture_Delete( p_subpic
);
738 /* Run user specified filter chain */
740 p_pic
= filter_chain_VideoFilter( id
->p_uf_chain
, p_pic
);
742 if( p_sys
->i_threads
== 0 )
746 video_timer_start( id
->p_encoder
);
747 p_block
= id
->p_encoder
->pf_encode_video( id
->p_encoder
, p_pic
);
748 video_timer_stop( id
->p_encoder
);
750 block_ChainAppend( out
, p_block
);
753 if( p_sys
->b_master_sync
)
755 mtime_t i_pts
= date_Get( &id
->interpolated_pts
) + 1;
756 if ( p_pic
->date
- i_pts
> MASTER_SYNC_MAX_DRIFT
757 || p_pic
->date
- i_pts
< -MASTER_SYNC_MAX_DRIFT
)
759 msg_Dbg( p_stream
, "drift is too high, resetting master sync" );
760 date_Set( &id
->interpolated_pts
, p_pic
->date
);
761 i_pts
= p_pic
->date
+ 1;
763 date_Increment( &id
->interpolated_pts
, 1 );
765 if( unlikely( b_need_duplicate
) )
768 if( p_sys
->i_threads
>= 1 )
770 /* We can't modify the picture, we need to duplicate it */
771 p_pic2
= video_new_buffer_decoder( id
->p_decoder
);
774 picture_Copy( p_pic2
, p_pic
);
775 p_pic2
->date
= i_pts
;
782 video_timer_start( id
->p_encoder
);
783 p_block
= id
->p_encoder
->pf_encode_video(id
->p_encoder
, p_pic
);
784 video_timer_stop( id
->p_encoder
);
785 block_ChainAppend( out
, p_block
);
790 if( p_sys
->i_threads
== 0 )
792 picture_Release( p_pic
);
796 vlc_mutex_lock( &p_sys
->lock_out
);
797 p_sys
->pp_pics
[p_sys
->i_last_pic
++] = p_pic
;
798 p_sys
->i_last_pic
%= PICTURE_RING_SIZE
;
799 *out
= p_sys
->p_buffers
;
800 p_sys
->p_buffers
= NULL
;
803 p_sys
->pp_pics
[p_sys
->i_last_pic
++] = p_pic2
;
804 p_sys
->i_last_pic
%= PICTURE_RING_SIZE
;
806 vlc_cond_signal( &p_sys
->cond
);
807 vlc_mutex_unlock( &p_sys
->lock_out
);
814 bool transcode_video_add( sout_stream_t
*p_stream
, es_format_t
*p_fmt
,
815 sout_stream_id_t
*id
)
817 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
820 "creating video transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
821 (char*)&p_fmt
->i_codec
, (char*)&p_sys
->i_vcodec
);
823 /* Complete destination format */
824 id
->p_encoder
->fmt_out
.i_codec
= p_sys
->i_vcodec
;
825 id
->p_encoder
->fmt_out
.video
.i_width
= p_sys
->i_width
& ~1;
826 id
->p_encoder
->fmt_out
.video
.i_height
= p_sys
->i_height
& ~1;
827 id
->p_encoder
->fmt_out
.i_bitrate
= p_sys
->i_vbitrate
;
829 /* Build decoder -> filter -> encoder chain */
830 if( transcode_video_new( p_stream
, id
) )
832 msg_Err( p_stream
, "cannot create video chain" );
836 /* Stream will be added later on because we don't know
837 * all the characteristics of the decoded stream yet */
838 id
->b_transcode
= true;
840 if( p_sys
->f_fps
> 0 )
842 id
->p_encoder
->fmt_out
.video
.i_frame_rate
= (p_sys
->f_fps
* 1000) + 0.5;
843 id
->p_encoder
->fmt_out
.video
.i_frame_rate_base
= ENC_FRAMERATE_BASE
;