1 /*****************************************************************************
2 * transcode.c: transcoding stream output module
3 *****************************************************************************
4 * Copyright (C) 2003-2008 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 *****************************************************************************/
34 #include <vlc_common.h>
35 #include <vlc_plugin.h>
36 #include <vlc_input.h>
40 #include <vlc_codec.h>
41 #include <vlc_block.h>
42 #include <vlc_filter.h>
47 #define MASTER_SYNC_MAX_DRIFT 100000
51 /*****************************************************************************
53 *****************************************************************************/
54 #define VENC_TEXT N_("Video encoder")
55 #define VENC_LONGTEXT N_( \
56 "This is the video encoder module that will be used (and its associated "\
58 #define VCODEC_TEXT N_("Destination video codec")
59 #define VCODEC_LONGTEXT N_( \
60 "This is the video codec that will be used.")
61 #define VB_TEXT N_("Video bitrate")
62 #define VB_LONGTEXT N_( \
63 "Target bitrate of the transcoded video stream." )
64 #define SCALE_TEXT N_("Video scaling")
65 #define SCALE_LONGTEXT N_( \
66 "Scale factor to apply to the video while transcoding (eg: 0.25)")
67 #define FPS_TEXT N_("Video frame-rate")
68 #define FPS_LONGTEXT N_( \
69 "Target output frame rate for the video stream." )
70 #define DEINTERLACE_TEXT N_("Deinterlace video")
71 #define DEINTERLACE_LONGTEXT N_( \
72 "Deinterlace the video before encoding." )
73 #define DEINTERLACE_MODULE_TEXT N_("Deinterlace module")
74 #define DEINTERLACE_MODULE_LONGTEXT N_( \
75 "Specify the deinterlace module to use." )
76 #define WIDTH_TEXT N_("Video width")
77 #define WIDTH_LONGTEXT N_( \
78 "Output video width." )
79 #define HEIGHT_TEXT N_("Video height")
80 #define HEIGHT_LONGTEXT N_( \
81 "Output video height." )
82 #define MAXWIDTH_TEXT N_("Maximum video width")
83 #define MAXWIDTH_LONGTEXT N_( \
84 "Maximum output video width." )
85 #define MAXHEIGHT_TEXT N_("Maximum video height")
86 #define MAXHEIGHT_LONGTEXT N_( \
87 "Maximum output video height." )
88 #define VFILTER_TEXT N_("Video filter")
89 #define VFILTER_LONGTEXT N_( \
90 "Video filters will be applied to the video streams (after overlays " \
91 "are applied). You must enter a comma-separated list of filters." )
93 #define AENC_TEXT N_("Audio encoder")
94 #define AENC_LONGTEXT N_( \
95 "This is the audio encoder module that will be used (and its associated "\
97 #define ACODEC_TEXT N_("Destination audio codec")
98 #define ACODEC_LONGTEXT N_( \
99 "This is the audio codec that will be used.")
100 #define AB_TEXT N_("Audio bitrate")
101 #define AB_LONGTEXT N_( \
102 "Target bitrate of the transcoded audio stream." )
103 #define ARATE_TEXT N_("Audio sample rate")
104 #define ARATE_LONGTEXT N_( \
105 "Sample rate of the transcoded audio stream (11250, 22500, 44100 or 48000).")
106 #define ACHANS_TEXT N_("Audio channels")
107 #define ACHANS_LONGTEXT N_( \
108 "Number of audio channels in the transcoded streams." )
109 #define AFILTER_TEXT N_("Audio filter")
110 #define AFILTER_LONGTEXT N_( \
111 "Audio filters will be applied to the audio streams (after conversion " \
112 "filters are applied). You must enter a comma-separated list of filters." )
114 #define SENC_TEXT N_("Subtitles encoder")
115 #define SENC_LONGTEXT N_( \
116 "This is the subtitles encoder module that will be used (and its " \
117 "associated options)." )
118 #define SCODEC_TEXT N_("Destination subtitles codec")
119 #define SCODEC_LONGTEXT N_( \
120 "This is the subtitles codec that will be used." )
122 #define SFILTER_TEXT N_("Overlays")
123 #define SFILTER_LONGTEXT N_( \
124 "This allows you to add overlays (also known as \"subpictures\" on the "\
125 "transcoded video stream. The subpictures produced by the filters will "\
126 "be overlayed directly onto the video. You must specify a comma-separated "\
127 "list of subpicture modules" )
129 #define OSD_TEXT N_("OSD menu")
130 #define OSD_LONGTEXT N_(\
131 "Stream the On Screen Display menu (using the osdmenu subpicture module)." )
133 #define THREADS_TEXT N_("Number of threads")
134 #define THREADS_LONGTEXT N_( \
135 "Number of threads used for the transcoding." )
136 #define HP_TEXT N_("High priority")
137 #define HP_LONGTEXT N_( \
138 "Runs the optional encoder thread at the OUTPUT priority instead of " \
141 #define ASYNC_TEXT N_("Synchronise on audio track")
142 #define ASYNC_LONGTEXT N_( \
143 "This option will drop/duplicate video frames to synchronise the video " \
144 "track on the audio track." )
146 #define HURRYUP_TEXT N_( "Hurry up" )
147 #define HURRYUP_LONGTEXT N_( "The transcoder will drop frames if your CPU " \
148 "can't keep up with the encoding rate." )
150 static const char *const ppsz_deinterlace_type[] =
152 "deinterlace", "ffmpeg-deinterlace"
155 static int Open ( vlc_object_t * );
156 static void Close( vlc_object_t * );
158 #define SOUT_CFG_PREFIX "sout-transcode-"
161 set_shortname( N_("Transcode"));
162 set_description( N_("Transcode stream output") );
163 set_capability( "sout stream", 50 );
164 add_shortcut( "transcode" );
165 set_callbacks( Open, Close );
166 set_category( CAT_SOUT );
167 set_subcategory( SUBCAT_SOUT_STREAM );
168 set_section( N_("Video"), NULL );
169 add_string( SOUT_CFG_PREFIX "venc", NULL, NULL, VENC_TEXT,
170 VENC_LONGTEXT, false );
171 add_string( SOUT_CFG_PREFIX "vcodec", NULL, NULL, VCODEC_TEXT,
172 VCODEC_LONGTEXT, false );
173 add_integer( SOUT_CFG_PREFIX "vb", 800 * 1000, NULL, VB_TEXT,
174 VB_LONGTEXT, false );
175 add_float( SOUT_CFG_PREFIX "scale", 1, NULL, SCALE_TEXT,
176 SCALE_LONGTEXT, false );
177 add_float( SOUT_CFG_PREFIX "fps", 0, NULL, FPS_TEXT,
178 FPS_LONGTEXT, false );
179 add_bool( SOUT_CFG_PREFIX "hurry-up", true, NULL, HURRYUP_TEXT,
180 HURRYUP_LONGTEXT, false );
181 add_bool( SOUT_CFG_PREFIX "deinterlace", 0, NULL, DEINTERLACE_TEXT,
182 DEINTERLACE_LONGTEXT, false );
183 add_string( SOUT_CFG_PREFIX "deinterlace-module", "deinterlace", NULL,
184 DEINTERLACE_MODULE_TEXT, DEINTERLACE_MODULE_LONGTEXT,
186 change_string_list( ppsz_deinterlace_type, 0, 0 );
187 add_integer( SOUT_CFG_PREFIX "width", 0, NULL, WIDTH_TEXT,
188 WIDTH_LONGTEXT, true );
189 add_integer( SOUT_CFG_PREFIX "height", 0, NULL, HEIGHT_TEXT,
190 HEIGHT_LONGTEXT, true );
191 add_integer( SOUT_CFG_PREFIX "maxwidth", 0, NULL, MAXWIDTH_TEXT,
192 MAXWIDTH_LONGTEXT, true );
193 add_integer( SOUT_CFG_PREFIX "maxheight", 0, NULL, MAXHEIGHT_TEXT,
194 MAXHEIGHT_LONGTEXT, true );
195 add_module_list( SOUT_CFG_PREFIX "vfilter", "video filter2",
197 VFILTER_TEXT, VFILTER_LONGTEXT, false );
199 set_section( N_("Audio"), NULL );
200 add_string( SOUT_CFG_PREFIX "aenc", NULL, NULL, AENC_TEXT,
201 AENC_LONGTEXT, false );
202 add_string( SOUT_CFG_PREFIX "acodec", NULL, NULL, ACODEC_TEXT,
203 ACODEC_LONGTEXT, false );
204 add_integer( SOUT_CFG_PREFIX "ab", 0, NULL, AB_TEXT,
205 AB_LONGTEXT, false );
206 add_integer( SOUT_CFG_PREFIX "channels", 0, NULL, ACHANS_TEXT,
207 ACHANS_LONGTEXT, false );
208 add_integer( SOUT_CFG_PREFIX "samplerate", 0, NULL, ARATE_TEXT,
209 ARATE_LONGTEXT, true );
210 add_bool( SOUT_CFG_PREFIX "audio-sync", 0, NULL, ASYNC_TEXT,
211 ASYNC_LONGTEXT, false );
212 add_module_list( SOUT_CFG_PREFIX "afilter", "audio filter2",
214 AFILTER_TEXT, AFILTER_LONGTEXT, false );
216 set_section( N_("Overlays/Subtitles"), NULL );
217 add_string( SOUT_CFG_PREFIX "senc", NULL, NULL, SENC_TEXT,
218 SENC_LONGTEXT, false );
219 add_string( SOUT_CFG_PREFIX "scodec", NULL, NULL, SCODEC_TEXT,
220 SCODEC_LONGTEXT, false );
221 add_bool( SOUT_CFG_PREFIX "soverlay", 0, NULL, SCODEC_TEXT,
222 SCODEC_LONGTEXT, false );
223 add_module_list( SOUT_CFG_PREFIX "sfilter", "video filter",
225 SFILTER_TEXT, SFILTER_LONGTEXT, false );
227 set_section( N_("On Screen Display"), NULL );
228 add_bool( SOUT_CFG_PREFIX "osd", 0, NULL, OSD_TEXT,
229 OSD_LONGTEXT, false );
231 set_section( N_("Miscellaneous"), NULL );
232 add_integer( SOUT_CFG_PREFIX "threads", 0, NULL, THREADS_TEXT,
233 THREADS_LONGTEXT, true );
234 add_bool( SOUT_CFG_PREFIX "high-priority", 0, NULL, HP_TEXT, HP_LONGTEXT,
239 static const char *const ppsz_sout_options[] = {
240 "venc", "vcodec", "vb",
241 "scale", "fps", "width", "height", "vfilter", "deinterlace",
242 "deinterlace-module", "threads", "hurry-up", "aenc", "acodec", "ab",
243 "afilter", "samplerate", "channels", "senc", "scodec", "soverlay",
244 "sfilter", "osd", "audio-sync", "high-priority", "maxwidth", "maxheight",
248 /*****************************************************************************
249 * Exported prototypes
250 *****************************************************************************/
251 static sout_stream_id_t *Add ( sout_stream_t *, es_format_t * );
252 static int Del ( sout_stream_t *, sout_stream_id_t * );
253 static int Send( sout_stream_t *, sout_stream_id_t *, block_t* );
255 static int transcode_audio_new ( sout_stream_t *, sout_stream_id_t * );
256 static void transcode_audio_close ( sout_stream_id_t * );
257 static int transcode_audio_process( sout_stream_t *, sout_stream_id_t *,
258 block_t *, block_t ** );
260 static aout_buffer_t *audio_new_buffer( decoder_t *, int );
261 static void audio_del_buffer( decoder_t *, aout_buffer_t * );
263 static int transcode_video_new ( sout_stream_t *, sout_stream_id_t * );
264 static void transcode_video_close ( sout_stream_t *, sout_stream_id_t * );
265 static void transcode_video_encoder_init( sout_stream_t *, sout_stream_id_t *);
266 static int transcode_video_encoder_open( sout_stream_t *, sout_stream_id_t *);
267 static int transcode_video_process( sout_stream_t *, sout_stream_id_t *,
268 block_t *, block_t ** );
270 static void video_del_buffer( vlc_object_t *, picture_t * );
271 static picture_t *video_new_buffer_decoder( decoder_t * );
272 static void video_del_buffer_decoder( decoder_t *, picture_t * );
273 static void video_link_picture_decoder( decoder_t *, picture_t * );
274 static void video_unlink_picture_decoder( decoder_t *, picture_t * );
275 static picture_t *video_new_buffer_filter( filter_t * );
276 static void video_del_buffer_filter( filter_t *, picture_t * );
278 static int transcode_spu_new ( sout_stream_t *, sout_stream_id_t * );
279 static void transcode_spu_close ( sout_stream_id_t * );
280 static int transcode_spu_process( sout_stream_t *, sout_stream_id_t *,
281 block_t *, block_t ** );
283 static int transcode_osd_new ( sout_stream_t *, sout_stream_id_t * );
284 static void transcode_osd_close ( sout_stream_t *, sout_stream_id_t * );
285 static int transcode_osd_process( sout_stream_t *, sout_stream_id_t *,
286 block_t *, block_t ** );
288 static int EncoderThread( struct sout_stream_sys_t * p_sys );
290 static int pi_channels_maps[6] =
293 AOUT_CHAN_CENTER, AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
294 AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
295 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
296 | AOUT_CHAN_REARRIGHT,
297 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
298 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
301 #define PICTURE_RING_SIZE 64
302 #define SUBPICTURE_RING_SIZE 20
304 #define ENC_FRAMERATE (25 * 1000 + .5)
305 #define ENC_FRAMERATE_BASE 1000
307 struct sout_stream_sys_t
311 sout_stream_t *p_out;
312 sout_stream_id_t *id_video;
314 vlc_mutex_t lock_out;
316 picture_t * pp_pics[PICTURE_RING_SIZE];
317 int i_first_pic, i_last_pic;
320 vlc_fourcc_t i_acodec; /* codec audio (0 if not transcode) */
322 config_chain_t *p_audio_cfg;
323 uint32_t i_sample_rate;
330 vlc_fourcc_t i_vcodec; /* codec video (0 if not transcode) */
332 config_chain_t *p_video_cfg;
336 unsigned int i_width, i_maxwidth;
337 unsigned int i_height, i_maxheight;
339 char *psz_deinterlace;
340 config_chain_t *p_deinterlace_cfg;
342 bool b_high_priority;
348 vlc_fourcc_t i_scodec; /* codec spu (0 if not transcode) */
351 config_chain_t *p_spu_cfg;
355 vlc_fourcc_t i_osdcodec; /* codec osd menu (0 if not transcode) */
357 config_chain_t *p_osd_cfg;
358 bool b_osd; /* true when osd es is registered */
362 mtime_t i_master_drift;
365 struct decoder_owner_sys_t
367 picture_t *pp_pics[PICTURE_RING_SIZE];
368 sout_stream_sys_t *p_sys;
370 struct filter_owner_sys_t
372 picture_t *pp_pics[PICTURE_RING_SIZE];
373 sout_stream_sys_t *p_sys;
376 /*****************************************************************************
378 *****************************************************************************/
379 static int Open( vlc_object_t *p_this )
381 sout_stream_t *p_stream = (sout_stream_t*)p_this;
382 sout_stream_sys_t *p_sys;
385 p_sys = vlc_object_create( p_this, sizeof( sout_stream_sys_t ) );
387 p_sys->p_out = sout_StreamNew( p_stream->p_sout, p_stream->psz_next );
390 msg_Err( p_stream, "cannot create chain" );
391 vlc_object_release( p_sys );
395 p_sys->i_master_drift = 0;
397 config_ChainParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options,
400 /* Audio transcoding parameters */
401 var_Get( p_stream, SOUT_CFG_PREFIX "aenc", &val );
402 p_sys->psz_aenc = NULL;
403 p_sys->p_audio_cfg = NULL;
404 if( val.psz_string && *val.psz_string )
407 psz_next = config_ChainCreate( &p_sys->psz_aenc, &p_sys->p_audio_cfg,
411 free( val.psz_string );
413 var_Get( p_stream, SOUT_CFG_PREFIX "acodec", &val );
415 if( val.psz_string && *val.psz_string )
418 memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) );
419 p_sys->i_acodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
421 free( val.psz_string );
423 var_Get( p_stream, SOUT_CFG_PREFIX "ab", &val );
424 p_sys->i_abitrate = val.i_int;
425 if( p_sys->i_abitrate < 4000 ) p_sys->i_abitrate *= 1000;
427 var_Get( p_stream, SOUT_CFG_PREFIX "samplerate", &val );
428 p_sys->i_sample_rate = val.i_int;
430 var_Get( p_stream, SOUT_CFG_PREFIX "channels", &val );
431 p_sys->i_channels = val.i_int;
433 if( p_sys->i_acodec )
435 if( p_sys->i_acodec == VLC_FOURCC('m','p','3',0) &&
436 p_sys->i_channels > 2 )
438 msg_Warn( p_stream, "%d channels invalid for mp3, forcing to 2",
440 p_sys->i_channels = 2;
442 msg_Dbg( p_stream, "codec audio=%4.4s %dHz %d channels %dKb/s",
443 (char *)&p_sys->i_acodec, p_sys->i_sample_rate,
444 p_sys->i_channels, p_sys->i_abitrate / 1000 );
447 var_Get( p_stream, SOUT_CFG_PREFIX "afilter", &val );
448 if( val.psz_string && *val.psz_string )
449 p_sys->psz_af2 = val.psz_string;
452 free( val.psz_string );
453 p_sys->psz_af2 = NULL;
456 /* Video transcoding parameters */
457 var_Get( p_stream, SOUT_CFG_PREFIX "venc", &val );
458 p_sys->psz_venc = NULL;
459 p_sys->p_video_cfg = NULL;
460 if( val.psz_string && *val.psz_string )
463 psz_next = config_ChainCreate( &p_sys->psz_venc, &p_sys->p_video_cfg,
467 free( val.psz_string );
469 var_Get( p_stream, SOUT_CFG_PREFIX "vcodec", &val );
471 if( val.psz_string && *val.psz_string )
474 memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) );
475 p_sys->i_vcodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
477 free( val.psz_string );
479 var_Get( p_stream, SOUT_CFG_PREFIX "vb", &val );
480 p_sys->i_vbitrate = val.i_int;
481 if( p_sys->i_vbitrate < 16000 ) p_sys->i_vbitrate *= 1000;
483 var_Get( p_stream, SOUT_CFG_PREFIX "scale", &val );
484 p_sys->f_scale = val.f_float;
486 var_Get( p_stream, SOUT_CFG_PREFIX "fps", &val );
487 p_sys->f_fps = val.f_float;
489 var_Get( p_stream, SOUT_CFG_PREFIX "hurry-up", &val );
490 p_sys->b_hurry_up = val.b_bool;
492 var_Get( p_stream, SOUT_CFG_PREFIX "width", &val );
493 p_sys->i_width = val.i_int;
495 var_Get( p_stream, SOUT_CFG_PREFIX "height", &val );
496 p_sys->i_height = val.i_int;
498 var_Get( p_stream, SOUT_CFG_PREFIX "maxwidth", &val );
499 p_sys->i_maxwidth = val.i_int;
501 var_Get( p_stream, SOUT_CFG_PREFIX "maxheight", &val );
502 p_sys->i_maxheight = val.i_int;
504 var_Get( p_stream, SOUT_CFG_PREFIX "vfilter", &val );
505 if( val.psz_string && *val.psz_string )
506 p_sys->psz_vf2 = val.psz_string;
509 free( val.psz_string );
510 p_sys->psz_vf2 = NULL;
513 var_Get( p_stream, SOUT_CFG_PREFIX "deinterlace", &val );
514 p_sys->b_deinterlace = val.b_bool;
516 var_Get( p_stream, SOUT_CFG_PREFIX "deinterlace-module", &val );
517 p_sys->psz_deinterlace = NULL;
518 p_sys->p_deinterlace_cfg = NULL;
519 if( val.psz_string && *val.psz_string )
522 psz_next = config_ChainCreate( &p_sys->psz_deinterlace,
523 &p_sys->p_deinterlace_cfg,
527 free( val.psz_string );
529 var_Get( p_stream, SOUT_CFG_PREFIX "threads", &val );
530 p_sys->i_threads = val.i_int;
531 var_Get( p_stream, SOUT_CFG_PREFIX "high-priority", &val );
532 p_sys->b_high_priority = val.b_bool;
534 if( p_sys->i_vcodec )
536 msg_Dbg( p_stream, "codec video=%4.4s %dx%d scaling: %f %dkb/s",
537 (char *)&p_sys->i_vcodec, p_sys->i_width, p_sys->i_height,
538 p_sys->f_scale, p_sys->i_vbitrate / 1000 );
541 /* Subpictures transcoding parameters */
543 p_sys->psz_senc = NULL;
544 p_sys->p_spu_cfg = NULL;
547 var_Get( p_stream, SOUT_CFG_PREFIX "senc", &val );
548 if( val.psz_string && *val.psz_string )
551 psz_next = config_ChainCreate( &p_sys->psz_senc, &p_sys->p_spu_cfg,
555 free( val.psz_string );
557 var_Get( p_stream, SOUT_CFG_PREFIX "scodec", &val );
558 if( val.psz_string && *val.psz_string )
561 memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) );
562 p_sys->i_scodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
564 free( val.psz_string );
566 if( p_sys->i_scodec )
568 msg_Dbg( p_stream, "codec spu=%4.4s", (char *)&p_sys->i_scodec );
571 var_Get( p_stream, SOUT_CFG_PREFIX "soverlay", &val );
572 p_sys->b_soverlay = val.b_bool;
574 var_Get( p_stream, SOUT_CFG_PREFIX "sfilter", &val );
575 if( val.psz_string && *val.psz_string )
577 p_sys->p_spu = spu_Create( p_stream );
578 var_Create( p_sys->p_spu, "sub-filter", VLC_VAR_STRING );
579 var_Set( p_sys->p_spu, "sub-filter", val );
580 spu_Init( p_sys->p_spu );
582 free( val.psz_string );
584 /* OSD menu transcoding parameters */
585 p_sys->psz_osdenc = NULL;
586 p_sys->p_osd_cfg = NULL;
587 p_sys->i_osdcodec = 0;
588 p_sys->b_osd = false;
590 var_Get( p_stream, SOUT_CFG_PREFIX "osd", &val );
596 psz_next = config_ChainCreate( &p_sys->psz_osdenc,
597 &p_sys->p_osd_cfg, strdup( "dvbsub") );
600 p_sys->i_osdcodec = VLC_FOURCC('Y','U','V','P' );
602 msg_Dbg( p_stream, "codec osd=%4.4s", (char *)&p_sys->i_osdcodec );
606 osd_val.psz_string = strdup("osdmenu");
607 p_sys->p_spu = spu_Create( p_stream );
608 var_Create( p_sys->p_spu, "sub-filter", VLC_VAR_STRING );
609 var_Set( p_sys->p_spu, "sub-filter", osd_val );
610 spu_Init( p_sys->p_spu );
611 free( osd_val.psz_string );
615 osd_val.psz_string = strdup("osdmenu");
616 var_Set( p_sys->p_spu, "sub-filter", osd_val );
617 free( osd_val.psz_string );
622 var_Get( p_stream, SOUT_CFG_PREFIX "audio-sync", &val );
623 p_sys->b_master_sync = val.b_bool;
624 if( p_sys->f_fps > 0 ) p_sys->b_master_sync = true;
626 p_stream->pf_add = Add;
627 p_stream->pf_del = Del;
628 p_stream->pf_send = Send;
629 p_stream->p_sys = p_sys;
634 /*****************************************************************************
636 *****************************************************************************/
637 static void Close( vlc_object_t * p_this )
639 sout_stream_t *p_stream = (sout_stream_t*)p_this;
640 sout_stream_sys_t *p_sys = p_stream->p_sys;
642 sout_StreamDelete( p_sys->p_out );
644 free( p_sys->psz_af2 );
646 while( p_sys->p_audio_cfg != NULL )
648 config_chain_t *p_next = p_sys->p_audio_cfg->p_next;
650 free( p_sys->p_audio_cfg->psz_name );
651 free( p_sys->p_audio_cfg->psz_value );
652 free( p_sys->p_audio_cfg );
654 p_sys->p_audio_cfg = p_next;
656 free( p_sys->psz_aenc );
658 free( p_sys->psz_vf2 );
660 while( p_sys->p_video_cfg != NULL )
662 config_chain_t *p_next = p_sys->p_video_cfg->p_next;
664 free( p_sys->p_video_cfg->psz_name );
665 free( p_sys->p_video_cfg->psz_value );
666 free( p_sys->p_video_cfg );
668 p_sys->p_video_cfg = p_next;
670 free( p_sys->psz_venc );
672 while( p_sys->p_deinterlace_cfg != NULL )
674 config_chain_t *p_next = p_sys->p_deinterlace_cfg->p_next;
676 free( p_sys->p_deinterlace_cfg->psz_name );
677 free( p_sys->p_deinterlace_cfg->psz_value );
678 free( p_sys->p_deinterlace_cfg );
680 p_sys->p_deinterlace_cfg = p_next;
682 free( p_sys->psz_deinterlace );
684 while( p_sys->p_spu_cfg != NULL )
686 config_chain_t *p_next = p_sys->p_spu_cfg->p_next;
688 free( p_sys->p_spu_cfg->psz_name );
689 free( p_sys->p_spu_cfg->psz_value );
690 free( p_sys->p_spu_cfg );
692 p_sys->p_spu_cfg = p_next;
694 free( p_sys->psz_senc );
696 if( p_sys->p_spu ) spu_Destroy( p_sys->p_spu );
698 while( p_sys->p_osd_cfg != NULL )
700 config_chain_t *p_next = p_sys->p_osd_cfg->p_next;
702 free( p_sys->p_osd_cfg->psz_name );
703 free( p_sys->p_osd_cfg->psz_value );
704 free( p_sys->p_osd_cfg );
706 p_sys->p_osd_cfg = p_next;
708 free( p_sys->psz_osdenc );
710 vlc_object_release( p_sys );
713 struct sout_stream_id_t
715 vlc_fourcc_t b_transcode;
717 /* id of the out stream */
721 decoder_t *p_decoder;
724 filter_chain_t *p_f_chain;
725 /* User specified filters */
726 filter_chain_t *p_uf_chain;
729 encoder_t *p_encoder;
732 date_t interpolated_pts;
735 static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
737 sout_stream_sys_t *p_sys = p_stream->p_sys;
738 sout_stream_id_t *id;
740 id = malloc( sizeof( sout_stream_id_t ) );
743 memset( id, 0, sizeof(sout_stream_id_t) );
746 id->p_decoder = NULL;
747 id->p_encoder = NULL;
749 /* Create decoder object */
750 id->p_decoder = vlc_object_create( p_stream, VLC_OBJECT_DECODER );
753 vlc_object_attach( id->p_decoder, p_stream );
754 id->p_decoder->p_module = NULL;
755 id->p_decoder->fmt_in = *p_fmt;
756 id->p_decoder->b_pace_control = true;
758 /* Create encoder object */
759 id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
762 vlc_object_attach( id->p_encoder, p_stream );
763 id->p_encoder->p_module = NULL;
765 /* Create destination format */
766 es_format_Init( &id->p_encoder->fmt_out, p_fmt->i_cat, 0 );
767 id->p_encoder->fmt_out.i_id = p_fmt->i_id;
768 id->p_encoder->fmt_out.i_group = p_fmt->i_group;
769 if( p_fmt->psz_language )
770 id->p_encoder->fmt_out.psz_language = strdup( p_fmt->psz_language );
772 if( p_fmt->i_cat == AUDIO_ES && (p_sys->i_acodec || p_sys->psz_aenc) )
775 "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
776 (char*)&p_fmt->i_codec, (char*)&p_sys->i_acodec );
778 /* Complete destination format */
779 id->p_encoder->fmt_out.i_codec = p_sys->i_acodec;
780 id->p_encoder->fmt_out.audio.i_rate = p_sys->i_sample_rate > 0 ?
781 p_sys->i_sample_rate : p_fmt->audio.i_rate;
782 id->p_encoder->fmt_out.i_bitrate = p_sys->i_abitrate;
783 id->p_encoder->fmt_out.audio.i_bitspersample =
784 p_fmt->audio.i_bitspersample;
785 id->p_encoder->fmt_out.audio.i_channels = p_sys->i_channels > 0 ?
786 p_sys->i_channels : p_fmt->audio.i_channels;
787 /* Sanity check for audio channels */
788 id->p_encoder->fmt_out.audio.i_channels =
789 __MIN( id->p_encoder->fmt_out.audio.i_channels,
790 id->p_decoder->fmt_in.audio.i_channels );
791 id->p_encoder->fmt_out.audio.i_original_channels =
792 id->p_decoder->fmt_in.audio.i_physical_channels;
793 if( id->p_decoder->fmt_in.audio.i_channels ==
794 id->p_encoder->fmt_out.audio.i_channels )
796 id->p_encoder->fmt_out.audio.i_physical_channels =
797 id->p_decoder->fmt_in.audio.i_physical_channels;
801 id->p_encoder->fmt_out.audio.i_physical_channels =
802 pi_channels_maps[id->p_encoder->fmt_out.audio.i_channels];
805 /* Build decoder -> filter -> encoder chain */
806 if( transcode_audio_new( p_stream, id ) )
808 msg_Err( p_stream, "cannot create audio chain" );
812 /* Open output stream */
813 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_encoder->fmt_out );
814 id->b_transcode = true;
818 transcode_audio_close( id );
822 date_Init( &id->interpolated_pts, p_fmt->audio.i_rate, 1 );
824 else if( p_fmt->i_cat == VIDEO_ES &&
825 (p_sys->i_vcodec != 0 || p_sys->psz_venc) )
828 "creating video transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
829 (char*)&p_fmt->i_codec, (char*)&p_sys->i_vcodec );
831 /* Complete destination format */
832 id->p_encoder->fmt_out.i_codec = p_sys->i_vcodec;
833 id->p_encoder->fmt_out.video.i_width = p_sys->i_width & ~1;
834 id->p_encoder->fmt_out.video.i_height = p_sys->i_height & ~1;
835 id->p_encoder->fmt_out.i_bitrate = p_sys->i_vbitrate;
837 /* Build decoder -> filter -> encoder chain */
838 if( transcode_video_new( p_stream, id ) )
840 msg_Err( p_stream, "cannot create video chain" );
844 /* Stream will be added later on because we don't know
845 * all the characteristics of the decoded stream yet */
846 id->b_transcode = true;
848 if( p_sys->f_fps > 0 )
850 id->p_encoder->fmt_out.video.i_frame_rate =
851 (p_sys->f_fps * 1000) + 0.5;
852 id->p_encoder->fmt_out.video.i_frame_rate_base =
856 else if( ( p_fmt->i_cat == SPU_ES ) &&
857 ( p_sys->i_scodec || p_sys->psz_senc ) )
859 msg_Dbg( p_stream, "creating subtitles transcoding from fcc=`%4.4s' "
860 "to fcc=`%4.4s'", (char*)&p_fmt->i_codec,
861 (char*)&p_sys->i_scodec );
863 /* Complete destination format */
864 id->p_encoder->fmt_out.i_codec = p_sys->i_scodec;
866 /* build decoder -> filter -> encoder */
867 if( transcode_spu_new( p_stream, id ) )
869 msg_Err( p_stream, "cannot create subtitles chain" );
873 /* open output stream */
874 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_encoder->fmt_out );
875 id->b_transcode = true;
879 transcode_spu_close( id );
883 else if( p_fmt->i_cat == SPU_ES && p_sys->b_soverlay )
885 msg_Dbg( p_stream, "subtitles (fcc=`%4.4s') overlaying",
886 (char*)&p_fmt->i_codec );
888 id->b_transcode = true;
890 /* Build decoder -> filter -> overlaying chain */
891 if( transcode_spu_new( p_stream, id ) )
893 msg_Err( p_stream, "cannot create subtitles chain" );
897 else if( !p_sys->b_osd && (p_sys->i_osdcodec != 0 || p_sys->psz_osdenc) )
899 msg_Dbg( p_stream, "creating osd transcoding from fcc=`%4.4s' "
900 "to fcc=`%4.4s'", (char*)&p_fmt->i_codec,
901 (char*)&p_sys->i_scodec );
903 id->b_transcode = true;
905 /* Create a fake OSD menu elementary stream */
906 if( transcode_osd_new( p_stream, id ) )
908 msg_Err( p_stream, "cannot create osd chain" );
915 msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
916 (char*)&p_fmt->i_codec );
917 id->id = p_sys->p_out->pf_add( p_sys->p_out, p_fmt );
918 id->b_transcode = false;
920 if( !id->id ) goto error;
930 vlc_object_detach( id->p_decoder );
931 vlc_object_release( id->p_decoder );
932 id->p_decoder = NULL;
937 vlc_object_detach( id->p_encoder );
938 es_format_Clean( &id->p_encoder->fmt_out );
939 vlc_object_release( id->p_encoder );
940 id->p_encoder = NULL;
948 static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
950 sout_stream_sys_t *p_sys = p_stream->p_sys;
952 if( id->b_transcode )
954 switch( id->p_decoder->fmt_in.i_cat )
957 transcode_audio_close( id );
960 transcode_video_close( p_stream, id );
964 transcode_osd_close( p_stream, id );
966 transcode_spu_close( id );
971 if( id->id ) p_sys->p_out->pf_del( p_sys->p_out, id->id );
975 vlc_object_detach( id->p_decoder );
976 vlc_object_release( id->p_decoder );
977 id->p_decoder = NULL;
982 vlc_object_detach( id->p_encoder );
983 es_format_Clean( &id->p_encoder->fmt_out );
984 vlc_object_release( id->p_encoder );
985 id->p_encoder = NULL;
992 static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
995 sout_stream_sys_t *p_sys = p_stream->p_sys;
996 block_t *p_out = NULL;
998 if( !id->b_transcode && id->id )
1000 return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer );
1002 else if( !id->b_transcode )
1004 block_Release( p_buffer );
1005 return VLC_EGENERIC;
1008 switch( id->p_decoder->fmt_in.i_cat )
1011 transcode_audio_process( p_stream, id, p_buffer, &p_out );
1015 if( transcode_video_process( p_stream, id, p_buffer, &p_out )
1018 return VLC_EGENERIC;
1023 /* Transcode OSD menu pictures. */
1026 if( transcode_osd_process( p_stream, id, p_buffer, &p_out ) !=
1029 return VLC_EGENERIC;
1032 else if ( transcode_spu_process( p_stream, id, p_buffer, &p_out ) !=
1035 return VLC_EGENERIC;
1041 block_Release( p_buffer );
1045 if( p_out ) return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_out );
1049 /****************************************************************************
1051 ****************************************************************************/
1052 static inline void video_timer_start( encoder_t * p_encoder )
1054 stats_TimerStart( p_encoder, "encoding video frame",
1055 STATS_TIMER_VIDEO_FRAME_ENCODING );
1058 static inline void video_timer_stop( encoder_t * p_encoder )
1060 stats_TimerStop( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1063 static inline void video_timer_close( encoder_t * p_encoder )
1065 stats_TimerDump( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1066 stats_TimerClean( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1069 static inline void audio_timer_start( encoder_t * p_encoder )
1071 stats_TimerStart( p_encoder, "encoding audio frame",
1072 STATS_TIMER_AUDIO_FRAME_ENCODING );
1075 static inline void audio_timer_stop( encoder_t * p_encoder )
1077 stats_TimerStop( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1080 static inline void audio_timer_close( encoder_t * p_encoder )
1082 stats_TimerDump( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1083 stats_TimerClean( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1086 /****************************************************************************
1087 * decoder reencoder part
1088 ****************************************************************************/
1090 static block_t *transcode_audio_alloc( filter_t *p_filter, int size )
1092 VLC_UNUSED( p_filter );
1093 return block_Alloc( size );
1096 static int transcode_audio_filter_allocation_init( filter_t *p_filter,
1100 p_filter->pf_audio_buffer_new = transcode_audio_alloc;
1104 static int transcode_audio_new( sout_stream_t *p_stream,
1105 sout_stream_id_t *id )
1107 sout_stream_sys_t *p_sys = p_stream->p_sys;
1108 es_format_t fmt_last;
1115 /* Initialization of decoder structures */
1116 id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1117 id->p_decoder->fmt_out.i_extra = 0;
1118 id->p_decoder->fmt_out.p_extra = 0;
1119 id->p_decoder->pf_decode_audio = NULL;
1120 id->p_decoder->pf_aout_buffer_new = audio_new_buffer;
1121 id->p_decoder->pf_aout_buffer_del = audio_del_buffer;
1122 /* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */
1124 id->p_decoder->p_module =
1125 module_Need( id->p_decoder, "decoder", "$codec", 0 );
1126 if( !id->p_decoder->p_module )
1128 msg_Err( p_stream, "cannot find audio decoder" );
1129 return VLC_EGENERIC;
1131 id->p_decoder->fmt_out.audio.i_bitspersample =
1132 aout_BitsPerSample( id->p_decoder->fmt_out.i_codec );
1133 fmt_last = id->p_decoder->fmt_out;
1134 /* Fix AAC SBR changing number of channels and sampling rate */
1135 if( !(id->p_decoder->fmt_in.i_codec == VLC_FOURCC('m','p','4','a') &&
1136 fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate &&
1137 fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels) )
1138 fmt_last.audio.i_rate = id->p_decoder->fmt_in.audio.i_rate;
1144 /* Initialization of encoder format structures */
1145 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1146 id->p_decoder->fmt_out.i_codec );
1147 id->p_encoder->fmt_in.audio.i_format = id->p_decoder->fmt_out.i_codec;
1149 id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;//id->p_encoder->fmt_out.audio.i_rate;
1150 id->p_encoder->fmt_in.audio.i_physical_channels =
1151 id->p_encoder->fmt_out.audio.i_physical_channels;
1152 id->p_encoder->fmt_in.audio.i_original_channels =
1153 id->p_encoder->fmt_out.audio.i_original_channels;
1154 id->p_encoder->fmt_in.audio.i_channels =
1155 id->p_encoder->fmt_out.audio.i_channels;
1156 id->p_encoder->fmt_in.audio.i_bitspersample =
1157 aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1159 id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1160 id->p_encoder->p_module =
1161 module_Need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1162 if( !id->p_encoder->p_module )
1164 msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)",
1165 p_sys->psz_aenc ? p_sys->psz_aenc : "any",
1166 (char *)&p_sys->i_acodec );
1167 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1168 id->p_decoder->p_module = NULL;
1169 return VLC_EGENERIC;
1171 id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1172 id->p_encoder->fmt_in.audio.i_bitspersample =
1173 aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1175 /* Init filter chain */
1176 id->p_f_chain = filter_chain_New( p_stream, "audio filter2", true,
1177 transcode_audio_filter_allocation_init, NULL, NULL );
1178 filter_chain_Reset( id->p_f_chain, &fmt_last, &id->p_encoder->fmt_in );
1180 /* Load conversion filters */
1181 if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels ||
1182 fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1184 /* We'll have to go through fl32 first */
1185 fmt_last.i_codec = fmt_last.audio.i_format = VLC_FOURCC('f','l','3','2');
1186 fmt_last.audio.i_bitspersample = aout_BitsPerSample( fmt_last.i_codec );
1187 filter_chain_AppendFilter( id->p_f_chain, NULL, NULL, NULL, &fmt_last );
1188 fmt_last = *filter_chain_GetFmtOut( id->p_f_chain );
1191 for( i = 0; i < 4; i++ )
1193 if( (fmt_last.audio.i_channels !=
1194 id->p_encoder->fmt_in.audio.i_channels) ||
1195 (fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate) ||
1196 (fmt_last.i_codec != id->p_encoder->fmt_in.i_codec) )
1198 filter_chain_AppendFilter( id->p_f_chain, NULL, NULL, &fmt_last, &id->p_encoder->fmt_in );
1199 fmt_last = *filter_chain_GetFmtOut( id->p_f_chain );
1203 /* Final checks to see if conversions were successful */
1204 if( fmt_last.i_codec != id->p_encoder->fmt_in.i_codec )
1206 msg_Err( p_stream, "no audio filter found (%4.4s->%4.4s)",
1207 (char *)&fmt_last.i_codec,
1208 (char *)&id->p_encoder->fmt_in.i_codec );
1209 transcode_audio_close( id );
1210 return VLC_EGENERIC;
1213 /* Load user specified audio filters now */
1214 if( p_sys->psz_af2 )
1216 id->p_uf_chain = filter_chain_New( p_stream, "audio filter2", false,
1217 transcode_audio_filter_allocation_init, NULL, NULL );
1218 filter_chain_Reset( id->p_uf_chain, &fmt_last, &id->p_encoder->fmt_in );
1219 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_af2 );
1222 if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels )
1225 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1226 id->p_encoder->p_module = NULL;
1228 /* This might work, but only if the encoder is restarted */
1229 id->p_encoder->fmt_in.audio.i_channels = fmt_last.audio.i_channels;
1230 id->p_encoder->fmt_out.audio.i_channels = fmt_last.audio.i_channels;
1232 id->p_encoder->fmt_in.audio.i_physical_channels =
1233 id->p_encoder->fmt_in.audio.i_original_channels =
1234 fmt_last.audio.i_physical_channels;
1235 id->p_encoder->fmt_out.audio.i_physical_channels =
1236 id->p_encoder->fmt_out.audio.i_original_channels =
1237 fmt_last.audio.i_physical_channels;
1239 msg_Dbg( p_stream, "number of audio channels for mixing changed, "
1240 "trying to reopen the encoder for mixing %i to %i channels",
1241 fmt_last.audio.i_channels,
1242 id->p_encoder->fmt_in.audio.i_channels );
1244 /* reload encoder */
1245 id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1246 id->p_encoder->p_module =
1247 module_Need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1248 if( !id->p_encoder->p_module )
1250 msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)",
1251 p_sys->psz_aenc ? p_sys->psz_aenc : "any",
1252 (char *)&p_sys->i_acodec );
1253 transcode_audio_close( id );
1254 return VLC_EGENERIC;
1256 id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1257 id->p_encoder->fmt_in.audio.i_bitspersample =
1258 aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1260 msg_Err( p_stream, "no audio filter found for mixing from"
1261 " %i to %i channels", fmt_last.audio.i_channels,
1262 id->p_encoder->fmt_in.audio.i_channels );
1264 transcode_audio_close( id );
1265 return VLC_EGENERIC;
1269 if( fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1271 msg_Err( p_stream, "no audio filter found for resampling from"
1272 " %iHz to %iHz", fmt_last.audio.i_rate,
1273 id->p_encoder->fmt_in.audio.i_rate );
1275 /* FIXME : this might work, but only if the encoder is restarted */
1276 id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;
1277 id->p_encoder->fmt_out.audio.i_rate = fmt_last.audio.i_rate;
1279 transcode_audio_close( id );
1280 return VLC_EGENERIC;
1284 /* FIXME: Hack for mp3 transcoding support */
1285 if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC( 'm','p','3',' ' ) )
1286 id->p_encoder->fmt_out.i_codec = VLC_FOURCC( 'm','p','g','a' );
1291 static void transcode_audio_close( sout_stream_id_t *id )
1293 audio_timer_close( id->p_encoder );
1296 if( id->p_decoder->p_module )
1297 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1298 id->p_decoder->p_module = NULL;
1301 if( id->p_encoder->p_module )
1302 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1303 id->p_encoder->p_module = NULL;
1307 filter_chain_Delete( id->p_f_chain );
1308 if( id->p_uf_chain )
1309 filter_chain_Delete( id->p_uf_chain );
1312 static int transcode_audio_process( sout_stream_t *p_stream,
1313 sout_stream_id_t *id,
1314 block_t *in, block_t **out )
1316 sout_stream_sys_t *p_sys = p_stream->p_sys;
1317 aout_buffer_t *p_audio_buf;
1318 block_t *p_block, *p_audio_block;
1321 while( (p_audio_buf = id->p_decoder->pf_decode_audio( id->p_decoder,
1324 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_AUDIO, 1 );
1325 if( p_sys->b_master_sync )
1327 mtime_t i_dts = date_Get( &id->interpolated_pts ) + 1;
1328 if ( p_audio_buf->start_date - i_dts > MASTER_SYNC_MAX_DRIFT
1329 || p_audio_buf->start_date - i_dts < -MASTER_SYNC_MAX_DRIFT )
1331 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1332 date_Set( &id->interpolated_pts, p_audio_buf->start_date );
1333 i_dts = p_audio_buf->start_date + 1;
1335 p_sys->i_master_drift = p_audio_buf->start_date - i_dts;
1336 date_Increment( &id->interpolated_pts, p_audio_buf->i_nb_samples );
1337 p_audio_buf->start_date -= p_sys->i_master_drift;
1338 p_audio_buf->end_date -= p_sys->i_master_drift;
1341 p_audio_block = p_audio_buf->p_sys;
1342 p_audio_block->i_buffer = p_audio_buf->i_nb_bytes;
1343 p_audio_block->i_dts = p_audio_block->i_pts =
1344 p_audio_buf->start_date;
1345 p_audio_block->i_length = p_audio_buf->end_date -
1346 p_audio_buf->start_date;
1347 p_audio_block->i_samples = p_audio_buf->i_nb_samples;
1349 /* Run filter chain */
1350 p_audio_block = filter_chain_AudioFilter( id->p_f_chain, p_audio_block );
1351 if( id->p_uf_chain )
1352 p_audio_block = filter_chain_AudioFilter( id->p_uf_chain, p_audio_block );
1353 assert( p_audio_block );
1355 p_audio_buf->p_buffer = p_audio_block->p_buffer;
1356 p_audio_buf->i_nb_bytes = p_audio_block->i_buffer;
1357 p_audio_buf->i_nb_samples = p_audio_block->i_samples;
1358 p_audio_buf->start_date = p_audio_block->i_dts;
1359 p_audio_buf->end_date = p_audio_block->i_dts + p_audio_block->i_length;
1361 audio_timer_start( id->p_encoder );
1362 p_block = id->p_encoder->pf_encode_audio( id->p_encoder, p_audio_buf );
1363 audio_timer_stop( id->p_encoder );
1365 block_ChainAppend( out, p_block );
1366 block_Release( p_audio_block );
1367 free( p_audio_buf );
1373 static void audio_release_buffer( aout_buffer_t *p_buffer )
1375 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1379 static aout_buffer_t *audio_new_buffer( decoder_t *p_dec, int i_samples )
1381 aout_buffer_t *p_buffer;
1385 if( p_dec->fmt_out.audio.i_bitspersample )
1387 i_size = i_samples * p_dec->fmt_out.audio.i_bitspersample / 8 *
1388 p_dec->fmt_out.audio.i_channels;
1390 else if( p_dec->fmt_out.audio.i_bytes_per_frame &&
1391 p_dec->fmt_out.audio.i_frame_length )
1393 i_size = i_samples * p_dec->fmt_out.audio.i_bytes_per_frame /
1394 p_dec->fmt_out.audio.i_frame_length;
1398 i_size = i_samples * 4 * p_dec->fmt_out.audio.i_channels;
1401 p_buffer = malloc( sizeof(aout_buffer_t) );
1402 if( !p_buffer ) return NULL;
1403 p_buffer->b_discontinuity = false;
1404 p_buffer->pf_release = audio_release_buffer;
1405 p_buffer->p_sys = p_block = block_New( p_dec, i_size );
1407 p_buffer->p_buffer = p_block->p_buffer;
1408 p_buffer->i_size = p_buffer->i_nb_bytes = p_block->i_buffer;
1409 p_buffer->i_nb_samples = i_samples;
1410 p_block->i_samples = i_samples;
1415 static void audio_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
1418 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1426 static int transcode_video_filter_allocation_init( filter_t *p_filter,
1429 sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_data;
1432 p_filter->pf_vout_buffer_new = video_new_buffer_filter;
1433 p_filter->pf_vout_buffer_del = video_del_buffer_filter;
1435 p_filter->p_owner = malloc( sizeof(filter_owner_sys_t) );
1436 if( !p_filter->p_owner )
1437 return VLC_EGENERIC;
1439 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1440 p_filter->p_owner->pp_pics[i] = 0;
1441 p_filter->p_owner->p_sys = p_sys;
1446 static void transcode_video_filter_allocation_clear( filter_t *p_filter )
1450 /* Clean-up pictures ring buffer */
1451 for( j = 0; j < PICTURE_RING_SIZE; j++ )
1453 if( p_filter->p_owner->pp_pics[j] )
1454 video_del_buffer( VLC_OBJECT(p_filter),
1455 p_filter->p_owner->pp_pics[j] );
1457 free( p_filter->p_owner );
1460 static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
1462 sout_stream_sys_t *p_sys = p_stream->p_sys;
1466 * Initialization of decoder structures
1468 id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1469 id->p_decoder->fmt_out.i_extra = 0;
1470 id->p_decoder->fmt_out.p_extra = 0;
1471 id->p_decoder->pf_decode_video = NULL;
1472 id->p_decoder->pf_get_cc = NULL;
1473 id->p_decoder->pf_get_cc = 0;
1474 id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
1475 id->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder;
1476 id->p_decoder->pf_picture_link = video_link_picture_decoder;
1477 id->p_decoder->pf_picture_unlink = video_unlink_picture_decoder;
1478 id->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) );
1479 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1480 id->p_decoder->p_owner->pp_pics[i] = 0;
1481 id->p_decoder->p_owner->p_sys = p_sys;
1482 /* id->p_decoder->p_cfg = p_sys->p_video_cfg; */
1484 id->p_decoder->p_module =
1485 module_Need( id->p_decoder, "decoder", "$codec", 0 );
1487 if( !id->p_decoder->p_module )
1489 msg_Err( p_stream, "cannot find video decoder" );
1490 return VLC_EGENERIC;
1495 * Because some info about the decoded input will only be available
1496 * once the first frame is decoded, we actually only test the availability
1497 * of the encoder here.
1500 /* Initialization of encoder format structures */
1501 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1502 id->p_decoder->fmt_out.i_codec );
1503 id->p_encoder->fmt_in.video.i_chroma = id->p_decoder->fmt_out.i_codec;
1505 /* The dimensions will be set properly later on.
1506 * Just put sensible values so we can test an encoder is available. */
1507 id->p_encoder->fmt_in.video.i_width =
1508 id->p_encoder->fmt_out.video.i_width ?:
1509 id->p_decoder->fmt_in.video.i_width ?: 16;
1510 id->p_encoder->fmt_in.video.i_height =
1511 id->p_encoder->fmt_out.video.i_height ?:
1512 id->p_decoder->fmt_in.video.i_height ?: 16;
1513 id->p_encoder->fmt_in.video.i_frame_rate = ENC_FRAMERATE;
1514 id->p_encoder->fmt_in.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1516 id->p_encoder->i_threads = p_sys->i_threads;
1517 id->p_encoder->p_cfg = p_sys->p_video_cfg;
1519 id->p_encoder->p_module =
1520 module_Need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1521 if( !id->p_encoder->p_module )
1523 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1524 p_sys->psz_venc ? p_sys->psz_venc : "any",
1525 (char *)&p_sys->i_vcodec );
1526 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1527 id->p_decoder->p_module = 0;
1528 return VLC_EGENERIC;
1531 /* Close the encoder.
1532 * We'll open it only when we have the first frame. */
1533 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1534 if( id->p_encoder->fmt_out.p_extra )
1536 free( id->p_encoder->fmt_out.p_extra );
1537 id->p_encoder->fmt_out.p_extra = NULL;
1538 id->p_encoder->fmt_out.i_extra = 0;
1540 id->p_encoder->p_module = NULL;
1542 if( p_sys->i_threads >= 1 )
1544 int i_priority = p_sys->b_high_priority ? VLC_THREAD_PRIORITY_OUTPUT :
1545 VLC_THREAD_PRIORITY_VIDEO;
1546 p_sys->id_video = id;
1547 vlc_mutex_init( &p_sys->lock_out );
1548 vlc_cond_init( p_stream, &p_sys->cond );
1549 memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) );
1550 p_sys->i_first_pic = 0;
1551 p_sys->i_last_pic = 0;
1552 p_sys->p_buffers = NULL;
1553 p_sys->b_die = p_sys->b_error = 0;
1554 if( vlc_thread_create( p_sys, "encoder", EncoderThread, i_priority,
1557 msg_Err( p_stream, "cannot spawn encoder thread" );
1558 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1559 id->p_decoder->p_module = 0;
1560 return VLC_EGENERIC;
1567 static void transcode_video_encoder_init( sout_stream_t *p_stream,
1568 sout_stream_id_t *id )
1570 sout_stream_sys_t *p_sys = p_stream->p_sys;
1572 /* Calculate scaling
1573 * width/height of source */
1574 int i_src_width = id->p_decoder->fmt_out.video.i_width;
1575 int i_src_height = id->p_decoder->fmt_out.video.i_height;
1577 /* with/height scaling */
1578 float f_scale_width = 1;
1579 float f_scale_height = 1;
1581 /* width/height of output stream */
1586 float f_aspect = (float)id->p_decoder->fmt_out.video.i_aspect /
1589 msg_Dbg( p_stream, "decoder aspect is %i:%i",
1590 id->p_decoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1592 /* Change f_aspect from source frame to source pixel */
1593 f_aspect = f_aspect * i_src_height / i_src_width;
1594 msg_Dbg( p_stream, "source pixel aspect is %f:1", f_aspect );
1596 /* Calculate scaling factor for specified parameters */
1597 if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1598 id->p_encoder->fmt_out.video.i_height <= 0 && p_sys->f_scale )
1600 /* Global scaling. Make sure width will remain a factor of 16 */
1603 int i_new_width = i_src_width * p_sys->f_scale;
1605 if( i_new_width % 16 <= 7 && i_new_width >= 16 )
1606 i_new_width -= i_new_width % 16;
1608 i_new_width += 16 - i_new_width % 16;
1610 f_real_scale = (float)( i_new_width ) / (float) i_src_width;
1612 i_new_height = __MAX( 16, i_src_height * (float)f_real_scale );
1614 f_scale_width = f_real_scale;
1615 f_scale_height = (float) i_new_height / (float) i_src_height;
1617 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1618 id->p_encoder->fmt_out.video.i_height <= 0 )
1620 /* Only width specified */
1621 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1622 f_scale_height = f_scale_width;
1624 else if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1625 id->p_encoder->fmt_out.video.i_height > 0 )
1627 /* Only height specified */
1628 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1629 f_scale_width = f_scale_height;
1631 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1632 id->p_encoder->fmt_out.video.i_height > 0 )
1634 /* Width and height specified */
1635 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1636 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1639 /* check maxwidth and maxheight
1641 if( p_sys->i_maxwidth && f_scale_width > (float)p_sys->i_maxwidth /
1644 f_scale_width = (float)p_sys->i_maxwidth / i_src_width;
1647 if( p_sys->i_maxheight && f_scale_height > (float)p_sys->i_maxheight /
1650 f_scale_height = (float)p_sys->i_maxheight / i_src_height;
1654 /* Change aspect ratio from source pixel to scaled pixel */
1655 f_aspect = f_aspect * f_scale_height / f_scale_width;
1656 msg_Dbg( p_stream, "scaled pixel aspect is %f:1", f_aspect );
1658 /* f_scale_width and f_scale_height are now final */
1659 /* Calculate width, height from scaling
1660 * Make sure its multiple of 2
1662 i_dst_width = 2 * (int)(f_scale_width*i_src_width/2+0.5);
1663 i_dst_height = 2 * (int)(f_scale_height*i_src_height/2+0.5);
1665 /* Change aspect ratio from scaled pixel to output frame */
1666 f_aspect = f_aspect * i_dst_width / i_dst_height;
1668 /* Store calculated values */
1669 id->p_encoder->fmt_out.video.i_width = i_dst_width;
1670 id->p_encoder->fmt_out.video.i_height = i_dst_height;
1672 id->p_encoder->fmt_in.video.i_width = i_dst_width;
1673 id->p_encoder->fmt_in.video.i_height = i_dst_height;
1675 msg_Dbg( p_stream, "source %ix%i, destination %ix%i",
1676 i_src_width, i_src_height,
1677 i_dst_width, i_dst_height
1680 /* Handle frame rate conversion */
1681 if( !id->p_encoder->fmt_out.video.i_frame_rate ||
1682 !id->p_encoder->fmt_out.video.i_frame_rate_base )
1684 if( id->p_decoder->fmt_out.video.i_frame_rate &&
1685 id->p_decoder->fmt_out.video.i_frame_rate_base )
1687 id->p_encoder->fmt_out.video.i_frame_rate =
1688 id->p_decoder->fmt_out.video.i_frame_rate;
1689 id->p_encoder->fmt_out.video.i_frame_rate_base =
1690 id->p_decoder->fmt_out.video.i_frame_rate_base;
1694 /* Pick a sensible default value */
1695 id->p_encoder->fmt_out.video.i_frame_rate = ENC_FRAMERATE;
1696 id->p_encoder->fmt_out.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1700 id->p_encoder->fmt_in.video.i_frame_rate =
1701 id->p_encoder->fmt_out.video.i_frame_rate;
1702 id->p_encoder->fmt_in.video.i_frame_rate_base =
1703 id->p_encoder->fmt_out.video.i_frame_rate_base;
1705 date_Init( &id->interpolated_pts,
1706 id->p_encoder->fmt_out.video.i_frame_rate,
1707 id->p_encoder->fmt_out.video.i_frame_rate_base );
1709 /* Check whether a particular aspect ratio was requested */
1710 if( !id->p_encoder->fmt_out.video.i_aspect )
1712 id->p_encoder->fmt_out.video.i_aspect =
1713 (int)( f_aspect * VOUT_ASPECT_FACTOR + 0.5 );
1715 id->p_encoder->fmt_in.video.i_aspect =
1716 id->p_encoder->fmt_out.video.i_aspect;
1718 msg_Dbg( p_stream, "encoder aspect is %i:%i",
1719 id->p_encoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1721 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1724 static int transcode_video_encoder_open( sout_stream_t *p_stream,
1725 sout_stream_id_t *id )
1727 sout_stream_sys_t *p_sys = p_stream->p_sys;
1730 msg_Dbg( p_stream, "destination (after video filters) %ix%i",
1731 id->p_encoder->fmt_in.video.i_width,
1732 id->p_encoder->fmt_in.video.i_height );
1734 id->p_encoder->p_module =
1735 module_Need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1736 if( !id->p_encoder->p_module )
1738 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1739 p_sys->psz_venc ? p_sys->psz_venc : "any",
1740 (char *)&p_sys->i_vcodec );
1741 return VLC_EGENERIC;
1744 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1746 /* Hack for mp2v/mp1v transcoding support */
1747 if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','1','v') ||
1748 id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','2','v') )
1750 id->p_encoder->fmt_out.i_codec = VLC_FOURCC('m','p','g','v');
1753 id->id = p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out,
1754 &id->p_encoder->fmt_out );
1757 msg_Err( p_stream, "cannot add this stream" );
1758 return VLC_EGENERIC;
1764 static void transcode_video_close( sout_stream_t *p_stream,
1765 sout_stream_id_t *id )
1769 if( p_stream->p_sys->i_threads >= 1 )
1771 vlc_mutex_lock( &p_stream->p_sys->lock_out );
1772 vlc_object_kill( p_stream->p_sys );
1773 vlc_cond_signal( &p_stream->p_sys->cond );
1774 vlc_mutex_unlock( &p_stream->p_sys->lock_out );
1775 vlc_thread_join( p_stream->p_sys );
1776 vlc_mutex_destroy( &p_stream->p_sys->lock_out );
1777 vlc_cond_destroy( &p_stream->p_sys->cond );
1780 video_timer_close( id->p_encoder );
1783 if( id->p_decoder->p_module )
1784 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1786 if( id->p_decoder->p_owner )
1788 /* Clean-up pictures ring buffer */
1789 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1791 if( id->p_decoder->p_owner->pp_pics[i] )
1792 video_del_buffer( VLC_OBJECT(id->p_decoder),
1793 id->p_decoder->p_owner->pp_pics[i] );
1795 free( id->p_decoder->p_owner );
1799 if( id->p_encoder->p_module )
1800 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1804 filter_chain_Delete( id->p_f_chain );
1805 if( id->p_uf_chain )
1806 filter_chain_Delete( id->p_uf_chain );
1809 static int transcode_video_process( sout_stream_t *p_stream,
1810 sout_stream_id_t *id,
1811 block_t *in, block_t **out )
1813 sout_stream_sys_t *p_sys = p_stream->p_sys;
1814 int i_duplicate = 1;
1815 picture_t *p_pic, *p_pic2 = NULL;
1818 while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
1820 subpicture_t *p_subpic = NULL;
1822 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_VIDEO, 1 );
1824 if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )
1826 mtime_t current_date = mdate();
1827 if( current_date + 50000 > p_pic->date )
1829 msg_Dbg( p_stream, "late picture skipped (%"PRId64")",
1830 current_date + 50000 - p_pic->date );
1831 p_pic->pf_release( p_pic );
1836 if( p_sys->b_master_sync )
1838 mtime_t i_video_drift;
1839 mtime_t i_master_drift = p_sys->i_master_drift;
1842 i_pts = date_Get( &id->interpolated_pts ) + 1;
1843 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1844 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
1846 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1847 date_Set( &id->interpolated_pts, p_pic->date );
1848 i_pts = p_pic->date + 1;
1850 i_video_drift = p_pic->date - i_pts;
1853 /* Set the pts of the frame being encoded */
1854 p_pic->date = i_pts;
1856 if( i_video_drift < (i_master_drift - 50000) )
1859 msg_Dbg( p_stream, "dropping frame (%i)",
1860 (int)(i_video_drift - i_master_drift) );
1862 p_pic->pf_release( p_pic );
1865 else if( i_video_drift > (i_master_drift + 50000) )
1868 msg_Dbg( p_stream, "adding frame (%i)",
1869 (int)(i_video_drift - i_master_drift) );
1875 if( !id->p_encoder->p_module )
1877 transcode_video_encoder_init( p_stream, id );
1879 id->p_f_chain = filter_chain_New( p_stream, "video filter2",
1881 transcode_video_filter_allocation_init,
1882 transcode_video_filter_allocation_clear,
1886 if( p_stream->p_sys->b_deinterlace )
1888 filter_chain_AppendFilter( id->p_f_chain,
1889 p_sys->psz_deinterlace,
1890 p_sys->p_deinterlace_cfg,
1891 &id->p_decoder->fmt_out,
1892 &id->p_decoder->fmt_out );
1895 /* Take care of the scaling and chroma conversions */
1896 if( ( id->p_decoder->fmt_out.video.i_chroma !=
1897 id->p_encoder->fmt_in.video.i_chroma ) ||
1898 ( id->p_decoder->fmt_out.video.i_width !=
1899 id->p_encoder->fmt_in.video.i_width ) ||
1900 ( id->p_decoder->fmt_out.video.i_height !=
1901 id->p_encoder->fmt_in.video.i_height ) )
1903 filter_chain_AppendFilter( id->p_f_chain,
1905 &id->p_decoder->fmt_out,
1906 &id->p_encoder->fmt_in );
1909 if( p_sys->psz_vf2 )
1911 const es_format_t *p_fmt_out;
1912 id->p_uf_chain = filter_chain_New( p_stream, "video filter2",
1914 transcode_video_filter_allocation_init,
1915 transcode_video_filter_allocation_clear,
1917 filter_chain_Reset( id->p_uf_chain, &id->p_decoder->fmt_out,
1918 &id->p_encoder->fmt_in );
1919 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_vf2 );
1920 p_fmt_out = filter_chain_GetFmtOut( id->p_uf_chain );
1921 es_format_Copy( &id->p_encoder->fmt_in, p_fmt_out );
1922 id->p_encoder->fmt_out.video.i_width =
1923 id->p_encoder->fmt_in.video.i_width;
1924 id->p_encoder->fmt_out.video.i_height =
1925 id->p_encoder->fmt_in.video.i_height;
1928 if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS )
1930 filter_chain_Delete( id->p_f_chain );
1931 if( id->p_uf_chain )
1932 filter_chain_Delete( id->p_uf_chain );
1933 p_pic->pf_release( p_pic );
1934 transcode_video_close( p_stream, id );
1935 id->b_transcode = false;
1936 return VLC_EGENERIC;
1940 /* Run filter chain */
1942 p_pic = filter_chain_VideoFilter( id->p_f_chain, p_pic );
1948 /* Check if we have a subpicture to overlay */
1951 p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date,
1952 false /* Fixme: check if stream is paused */ );
1953 /* TODO: get another pic */
1956 /* Overlay subpicture */
1959 int i_scale_width, i_scale_height;
1962 i_scale_width = id->p_encoder->fmt_in.video.i_width * 1000 /
1963 id->p_decoder->fmt_out.video.i_width;
1964 i_scale_height = id->p_encoder->fmt_in.video.i_height * 1000 /
1965 id->p_decoder->fmt_out.video.i_height;
1967 if( p_pic->i_refcount && !filter_chain_GetLength( id->p_f_chain ) )
1969 /* We can't modify the picture, we need to duplicate it */
1970 picture_t *p_tmp = video_new_buffer_decoder( id->p_decoder );
1973 vout_CopyPicture( p_stream, p_tmp, p_pic );
1974 p_pic->pf_release( p_pic );
1979 fmt = filter_chain_GetFmtOut( id->p_f_chain )->video;
1981 /* FIXME (shouldn't have to be done here) */
1982 fmt.i_sar_num = fmt.i_aspect * fmt.i_height / fmt.i_width;
1983 fmt.i_sar_den = VOUT_ASPECT_FACTOR;
1985 spu_RenderSubpictures( p_sys->p_spu, &fmt, p_pic, p_pic, p_subpic,
1986 i_scale_width, i_scale_height );
1989 /* Run user specified filter chain */
1990 if( id->p_uf_chain )
1991 p_pic = filter_chain_VideoFilter( id->p_uf_chain, p_pic );
1993 if( p_sys->i_threads == 0 )
1997 video_timer_start( id->p_encoder );
1998 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
1999 video_timer_stop( id->p_encoder );
2001 block_ChainAppend( out, p_block );
2004 if( p_sys->b_master_sync )
2006 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
2007 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
2008 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
2010 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2011 date_Set( &id->interpolated_pts, p_pic->date );
2012 i_pts = p_pic->date + 1;
2014 date_Increment( &id->interpolated_pts, 1 );
2017 if( p_sys->b_master_sync && i_duplicate > 1 )
2019 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
2020 if( (p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT)
2021 || ((p_pic->date - i_pts) < -MASTER_SYNC_MAX_DRIFT) )
2023 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2024 date_Set( &id->interpolated_pts, p_pic->date );
2025 i_pts = p_pic->date + 1;
2027 date_Increment( &id->interpolated_pts, 1 );
2029 if( p_sys->i_threads >= 1 )
2031 /* We can't modify the picture, we need to duplicate it */
2032 p_pic2 = video_new_buffer_decoder( id->p_decoder );
2033 if( p_pic2 != NULL )
2035 vout_CopyPicture( p_stream, p_pic2, p_pic );
2036 p_pic2->date = i_pts;
2042 p_pic->date = i_pts;
2043 video_timer_start( id->p_encoder );
2044 p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);
2045 video_timer_stop( id->p_encoder );
2046 block_ChainAppend( out, p_block );
2050 if( p_sys->i_threads == 0 )
2052 p_pic->pf_release( p_pic );
2056 vlc_mutex_lock( &p_sys->lock_out );
2057 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
2058 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2059 *out = p_sys->p_buffers;
2060 p_sys->p_buffers = NULL;
2061 if( p_pic2 != NULL )
2063 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic2;
2064 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2066 vlc_cond_signal( &p_sys->cond );
2067 vlc_mutex_unlock( &p_sys->lock_out );
2074 static int EncoderThread( sout_stream_sys_t *p_sys )
2076 sout_stream_id_t *id = p_sys->id_video;
2079 while( !p_sys->b_die && !p_sys->b_error )
2083 vlc_mutex_lock( &p_sys->lock_out );
2084 while( p_sys->i_last_pic == p_sys->i_first_pic )
2086 vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );
2087 if( p_sys->b_die || p_sys->b_error ) break;
2089 if( p_sys->b_die || p_sys->b_error )
2091 vlc_mutex_unlock( &p_sys->lock_out );
2095 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2096 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2097 vlc_mutex_unlock( &p_sys->lock_out );
2099 video_timer_start( id->p_encoder );
2100 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2101 video_timer_stop( id->p_encoder );
2103 vlc_mutex_lock( &p_sys->lock_out );
2104 block_ChainAppend( &p_sys->p_buffers, p_block );
2106 vlc_mutex_unlock( &p_sys->lock_out );
2107 p_pic->pf_release( p_pic );
2110 while( p_sys->i_last_pic != p_sys->i_first_pic )
2112 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2113 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2114 p_pic->pf_release( p_pic );
2116 block_ChainRelease( p_sys->p_buffers );
2121 struct picture_sys_t
2123 vlc_object_t *p_owner;
2126 static void video_release_buffer( picture_t *p_pic )
2128 if( p_pic && !p_pic->i_refcount && p_pic->pf_release && p_pic->p_sys )
2130 video_del_buffer_decoder( (decoder_t *)p_pic->p_sys->p_owner, p_pic );
2132 else if( p_pic && p_pic->i_refcount > 0 ) p_pic->i_refcount--;
2135 static picture_t *video_new_buffer( vlc_object_t *p_this, picture_t **pp_ring,
2136 sout_stream_sys_t *p_sys )
2138 decoder_t *p_dec = (decoder_t *)p_this;
2142 /* Find an empty space in the picture ring buffer */
2143 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2145 if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2147 pp_ring[i]->i_status = RESERVED_PICTURE;
2151 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2153 if( pp_ring[i] == 0 ) break;
2156 if( i == PICTURE_RING_SIZE && p_sys->i_threads >= 1 )
2158 int i_first_pic = p_sys->i_first_pic;
2160 if( p_sys->i_first_pic != p_sys->i_last_pic )
2162 /* Encoder still has stuff to encode, wait to clear-up the list */
2163 while( p_sys->i_first_pic == i_first_pic )
2167 /* Find an empty space in the picture ring buffer */
2168 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2170 if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2172 pp_ring[i]->i_status = RESERVED_PICTURE;
2176 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2178 if( pp_ring[i] == 0 ) break;
2182 if( i == PICTURE_RING_SIZE )
2184 msg_Err( p_this, "decoder/filter is leaking pictures, "
2185 "resetting its ring buffer" );
2187 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2189 pp_ring[i]->pf_release( pp_ring[i] );
2195 p_pic = malloc( sizeof(picture_t) );
2196 if( !p_pic ) return NULL;
2197 p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
2198 vout_AllocatePicture( VLC_OBJECT(p_dec), p_pic,
2199 p_dec->fmt_out.video.i_chroma,
2200 p_dec->fmt_out.video.i_width,
2201 p_dec->fmt_out.video.i_height,
2202 p_dec->fmt_out.video.i_aspect );
2204 if( !p_pic->i_planes )
2210 p_pic->pf_release = video_release_buffer;
2211 p_pic->p_sys = malloc( sizeof(picture_sys_t) );
2218 p_pic->p_sys->p_owner = p_this;
2219 p_pic->i_status = RESERVED_PICTURE;
2225 static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
2227 return video_new_buffer( VLC_OBJECT(p_dec),
2228 p_dec->p_owner->pp_pics, p_dec->p_owner->p_sys );
2231 static picture_t *video_new_buffer_filter( filter_t *p_filter )
2233 return video_new_buffer( VLC_OBJECT(p_filter),
2234 p_filter->p_owner->pp_pics,
2235 p_filter->p_owner->p_sys );
2238 static void video_del_buffer( vlc_object_t *p_this, picture_t *p_pic )
2243 free( p_pic->p_data_orig );
2244 free( p_pic->p_sys );
2249 static void video_del_buffer_decoder( decoder_t *p_decoder, picture_t *p_pic )
2251 VLC_UNUSED(p_decoder);
2252 p_pic->i_refcount = 0;
2253 p_pic->i_status = DESTROYED_PICTURE;
2256 static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic )
2258 VLC_UNUSED(p_filter);
2259 p_pic->i_refcount = 0;
2260 p_pic->i_status = DESTROYED_PICTURE;
2263 static void video_link_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2266 p_pic->i_refcount++;
2269 static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2272 video_release_buffer( p_pic );
2278 static subpicture_t *spu_new_buffer( decoder_t * );
2279 static void spu_del_buffer( decoder_t *, subpicture_t * );
2281 static int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2283 sout_stream_sys_t *p_sys = p_stream->p_sys;
2289 /* Initialization of decoder structures */
2290 id->p_decoder->pf_decode_sub = NULL;
2291 id->p_decoder->pf_spu_buffer_new = spu_new_buffer;
2292 id->p_decoder->pf_spu_buffer_del = spu_del_buffer;
2293 id->p_decoder->p_owner = (decoder_owner_sys_t *)p_stream;
2294 /* id->p_decoder->p_cfg = p_sys->p_spu_cfg; */
2296 id->p_decoder->p_module =
2297 module_Need( id->p_decoder, "decoder", "$codec", 0 );
2299 if( !id->p_decoder->p_module )
2301 msg_Err( p_stream, "cannot find spu decoder" );
2302 return VLC_EGENERIC;
2305 if( !p_sys->b_soverlay )
2308 /* Initialization of encoder format structures */
2309 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2310 id->p_decoder->fmt_in.i_codec );
2312 id->p_encoder->p_cfg = p_sys->p_spu_cfg;
2314 id->p_encoder->p_module =
2315 module_Need( id->p_encoder, "encoder", p_sys->psz_senc, true );
2317 if( !id->p_encoder->p_module )
2319 module_Unneed( id->p_decoder, id->p_decoder->p_module );
2320 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_senc );
2321 return VLC_EGENERIC;
2327 p_sys->p_spu = spu_Create( p_stream );
2328 spu_Init( p_sys->p_spu );
2334 static void transcode_spu_close( sout_stream_id_t *id)
2337 if( id->p_decoder->p_module )
2338 module_Unneed( id->p_decoder, id->p_decoder->p_module );
2341 if( id->p_encoder->p_module )
2342 module_Unneed( id->p_encoder, id->p_encoder->p_module );
2345 static int transcode_spu_process( sout_stream_t *p_stream,
2346 sout_stream_id_t *id,
2347 block_t *in, block_t **out )
2349 sout_stream_sys_t *p_sys = p_stream->p_sys;
2350 subpicture_t *p_subpic;
2353 p_subpic = id->p_decoder->pf_decode_sub( id->p_decoder, &in );
2355 return VLC_EGENERIC;
2357 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_SUBTITLE, 1 );
2359 if( p_sys->b_master_sync && p_sys->i_master_drift )
2361 p_subpic->i_start -= p_sys->i_master_drift;
2362 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2365 if( p_sys->b_soverlay )
2367 spu_DisplaySubpicture( p_sys->p_spu, p_subpic );
2373 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2374 spu_del_buffer( id->p_decoder, p_subpic );
2377 block_ChainAppend( out, p_block );
2382 return VLC_EGENERIC;
2385 static subpicture_t *spu_new_buffer( decoder_t *p_dec )
2387 sout_stream_t *p_stream = (sout_stream_t *)p_dec->p_owner;
2388 return spu_CreateSubpicture( p_stream->p_sys->p_spu );
2391 static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
2393 sout_stream_t *p_stream = (sout_stream_t *)p_dec->p_owner;
2394 spu_DestroySubpicture( p_stream->p_sys->p_spu, p_subpic );
2400 static int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2402 sout_stream_sys_t *p_sys = p_stream->p_sys;
2404 id->p_decoder->fmt_in.i_cat = SPU_ES;
2405 id->p_encoder->fmt_out.psz_language = strdup( "osd" );
2407 if( p_sys->i_osdcodec != 0 || p_sys->psz_osdenc )
2409 msg_Dbg( p_stream, "creating osdmenu transcoding from fcc=`%4.4s' "
2410 "to fcc=`%4.4s'", (char*)&id->p_encoder->fmt_out.i_codec,
2411 (char*)&p_sys->i_osdcodec );
2413 /* Complete destination format */
2414 id->p_encoder->fmt_out.i_codec = p_sys->i_osdcodec;
2417 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2418 VLC_FOURCC('Y','U','V','A') );
2419 id->p_encoder->fmt_in.psz_language = strdup( "osd" );
2421 id->p_encoder->p_cfg = p_sys->p_osd_cfg;
2423 id->p_encoder->p_module =
2424 module_Need( id->p_encoder, "encoder", p_sys->psz_osdenc, true );
2426 if( !id->p_encoder->p_module )
2428 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_osdenc );
2432 /* open output stream */
2433 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_encoder->fmt_out );
2434 id->b_transcode = true;
2436 if( !id->id ) goto error;
2440 msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
2441 (char*)&id->p_decoder->fmt_out.i_codec );
2442 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_decoder->fmt_out );
2443 id->b_transcode = false;
2445 if( !id->id ) goto error;
2450 p_sys->p_spu = spu_Create( p_stream );
2451 spu_Init( p_sys->p_spu );
2457 msg_Err( p_stream, "starting osd encoding thread failed" );
2458 if( id->p_encoder->p_module )
2459 module_Unneed( id->p_encoder, id->p_encoder->p_module );
2460 p_sys->b_osd = false;
2461 return VLC_EGENERIC;
2464 static void transcode_osd_close( sout_stream_t *p_stream, sout_stream_id_t *id)
2466 sout_stream_sys_t *p_sys = p_stream->p_sys;
2471 if( id->p_encoder->p_module )
2472 module_Unneed( id->p_encoder, id->p_encoder->p_module );
2474 p_sys->b_osd = false;
2477 static int transcode_osd_process( sout_stream_t *p_stream,
2478 sout_stream_id_t *id,
2479 block_t *in, block_t **out )
2481 sout_stream_sys_t *p_sys = p_stream->p_sys;
2482 subpicture_t *p_subpic = NULL;
2484 /* Check if we have a subpicture to send */
2485 if( p_sys->p_spu && in->i_dts > 0)
2487 p_subpic = spu_SortSubpictures( p_sys->p_spu, in->i_dts, false );
2491 msg_Warn( p_stream, "spu channel not initialized, doing it now" );
2494 p_sys->p_spu = spu_Create( p_stream );
2495 spu_Init( p_sys->p_spu );
2501 block_t *p_block = NULL;
2503 if( p_sys->b_master_sync && p_sys->i_master_drift )
2505 p_subpic->i_start -= p_sys->i_master_drift;
2506 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2509 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2510 spu_DestroySubpicture( p_sys->p_spu, p_subpic );
2513 p_block->i_dts = p_block->i_pts = in->i_dts;
2514 block_ChainAppend( out, p_block );
2518 return VLC_EGENERIC;