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 msg_Err( p_stream, "out of memory" );
746 memset( id, 0, sizeof(sout_stream_id_t) );
749 id->p_decoder = NULL;
750 id->p_encoder = NULL;
752 /* Create decoder object */
753 id->p_decoder = vlc_object_create( p_stream, VLC_OBJECT_DECODER );
756 msg_Err( p_stream, "out of memory" );
759 vlc_object_attach( id->p_decoder, p_stream );
760 id->p_decoder->p_module = NULL;
761 id->p_decoder->fmt_in = *p_fmt;
762 id->p_decoder->b_pace_control = true;
764 /* Create encoder object */
765 id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
768 msg_Err( p_stream, "out of memory" );
771 vlc_object_attach( id->p_encoder, p_stream );
772 id->p_encoder->p_module = NULL;
774 /* Create destination format */
775 es_format_Init( &id->p_encoder->fmt_out, p_fmt->i_cat, 0 );
776 id->p_encoder->fmt_out.i_id = p_fmt->i_id;
777 id->p_encoder->fmt_out.i_group = p_fmt->i_group;
778 if( p_fmt->psz_language )
779 id->p_encoder->fmt_out.psz_language = strdup( p_fmt->psz_language );
781 if( p_fmt->i_cat == AUDIO_ES && (p_sys->i_acodec || p_sys->psz_aenc) )
784 "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
785 (char*)&p_fmt->i_codec, (char*)&p_sys->i_acodec );
787 /* Complete destination format */
788 id->p_encoder->fmt_out.i_codec = p_sys->i_acodec;
789 id->p_encoder->fmt_out.audio.i_rate = p_sys->i_sample_rate > 0 ?
790 p_sys->i_sample_rate : p_fmt->audio.i_rate;
791 id->p_encoder->fmt_out.i_bitrate = p_sys->i_abitrate;
792 id->p_encoder->fmt_out.audio.i_bitspersample =
793 p_fmt->audio.i_bitspersample;
794 id->p_encoder->fmt_out.audio.i_channels = p_sys->i_channels > 0 ?
795 p_sys->i_channels : p_fmt->audio.i_channels;
796 /* Sanity check for audio channels */
797 id->p_encoder->fmt_out.audio.i_channels =
798 __MIN( id->p_encoder->fmt_out.audio.i_channels,
799 id->p_decoder->fmt_in.audio.i_channels );
800 id->p_encoder->fmt_out.audio.i_original_channels =
801 id->p_decoder->fmt_in.audio.i_physical_channels;
802 if( id->p_decoder->fmt_in.audio.i_channels ==
803 id->p_encoder->fmt_out.audio.i_channels )
805 id->p_encoder->fmt_out.audio.i_physical_channels =
806 id->p_decoder->fmt_in.audio.i_physical_channels;
810 id->p_encoder->fmt_out.audio.i_physical_channels =
811 pi_channels_maps[id->p_encoder->fmt_out.audio.i_channels];
814 /* Build decoder -> filter -> encoder chain */
815 if( transcode_audio_new( p_stream, id ) )
817 msg_Err( p_stream, "cannot create audio chain" );
821 /* Open output stream */
822 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_encoder->fmt_out );
823 id->b_transcode = true;
827 transcode_audio_close( id );
831 date_Init( &id->interpolated_pts, p_fmt->audio.i_rate, 1 );
833 else if( p_fmt->i_cat == VIDEO_ES &&
834 (p_sys->i_vcodec != 0 || p_sys->psz_venc) )
837 "creating video transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
838 (char*)&p_fmt->i_codec, (char*)&p_sys->i_vcodec );
840 /* Complete destination format */
841 id->p_encoder->fmt_out.i_codec = p_sys->i_vcodec;
842 id->p_encoder->fmt_out.video.i_width = p_sys->i_width & ~1;
843 id->p_encoder->fmt_out.video.i_height = p_sys->i_height & ~1;
844 id->p_encoder->fmt_out.i_bitrate = p_sys->i_vbitrate;
846 /* Build decoder -> filter -> encoder chain */
847 if( transcode_video_new( p_stream, id ) )
849 msg_Err( p_stream, "cannot create video chain" );
853 /* Stream will be added later on because we don't know
854 * all the characteristics of the decoded stream yet */
855 id->b_transcode = true;
857 if( p_sys->f_fps > 0 )
859 id->p_encoder->fmt_out.video.i_frame_rate =
860 (p_sys->f_fps * 1000) + 0.5;
861 id->p_encoder->fmt_out.video.i_frame_rate_base =
865 else if( ( p_fmt->i_cat == SPU_ES ) &&
866 ( p_sys->i_scodec || p_sys->psz_senc ) )
868 msg_Dbg( p_stream, "creating subtitles transcoding from fcc=`%4.4s' "
869 "to fcc=`%4.4s'", (char*)&p_fmt->i_codec,
870 (char*)&p_sys->i_scodec );
872 /* Complete destination format */
873 id->p_encoder->fmt_out.i_codec = p_sys->i_scodec;
875 /* build decoder -> filter -> encoder */
876 if( transcode_spu_new( p_stream, id ) )
878 msg_Err( p_stream, "cannot create subtitles chain" );
882 /* open output stream */
883 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_encoder->fmt_out );
884 id->b_transcode = true;
888 transcode_spu_close( id );
892 else if( p_fmt->i_cat == SPU_ES && p_sys->b_soverlay )
894 msg_Dbg( p_stream, "subtitles (fcc=`%4.4s') overlaying",
895 (char*)&p_fmt->i_codec );
897 id->b_transcode = true;
899 /* Build decoder -> filter -> overlaying chain */
900 if( transcode_spu_new( p_stream, id ) )
902 msg_Err( p_stream, "cannot create subtitles chain" );
906 else if( !p_sys->b_osd && (p_sys->i_osdcodec != 0 || p_sys->psz_osdenc) )
908 msg_Dbg( p_stream, "creating osd transcoding from fcc=`%4.4s' "
909 "to fcc=`%4.4s'", (char*)&p_fmt->i_codec,
910 (char*)&p_sys->i_scodec );
912 id->b_transcode = true;
914 /* Create a fake OSD menu elementary stream */
915 if( transcode_osd_new( p_stream, id ) )
917 msg_Err( p_stream, "cannot create osd chain" );
924 msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
925 (char*)&p_fmt->i_codec );
926 id->id = p_sys->p_out->pf_add( p_sys->p_out, p_fmt );
927 id->b_transcode = false;
929 if( !id->id ) goto error;
937 vlc_object_detach( id->p_decoder );
938 vlc_object_release( id->p_decoder );
939 id->p_decoder = NULL;
944 vlc_object_detach( id->p_encoder );
945 es_format_Clean( &id->p_encoder->fmt_out );
946 vlc_object_release( id->p_encoder );
947 id->p_encoder = NULL;
954 static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
956 sout_stream_sys_t *p_sys = p_stream->p_sys;
958 if( id->b_transcode )
960 switch( id->p_decoder->fmt_in.i_cat )
963 transcode_audio_close( id );
966 transcode_video_close( p_stream, id );
970 transcode_osd_close( p_stream, id );
972 transcode_spu_close( id );
977 if( id->id ) p_sys->p_out->pf_del( p_sys->p_out, id->id );
981 vlc_object_detach( id->p_decoder );
982 vlc_object_release( id->p_decoder );
983 id->p_decoder = NULL;
988 vlc_object_detach( id->p_encoder );
989 es_format_Clean( &id->p_encoder->fmt_out );
990 vlc_object_release( id->p_encoder );
991 id->p_encoder = NULL;
998 static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
1001 sout_stream_sys_t *p_sys = p_stream->p_sys;
1002 block_t *p_out = NULL;
1004 if( !id->b_transcode && id->id )
1006 return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer );
1008 else if( !id->b_transcode )
1010 block_Release( p_buffer );
1011 return VLC_EGENERIC;
1014 switch( id->p_decoder->fmt_in.i_cat )
1017 transcode_audio_process( p_stream, id, p_buffer, &p_out );
1021 if( transcode_video_process( p_stream, id, p_buffer, &p_out )
1024 return VLC_EGENERIC;
1029 /* Transcode OSD menu pictures. */
1032 if( transcode_osd_process( p_stream, id, p_buffer, &p_out ) !=
1035 return VLC_EGENERIC;
1038 else if ( transcode_spu_process( p_stream, id, p_buffer, &p_out ) !=
1041 return VLC_EGENERIC;
1047 block_Release( p_buffer );
1051 if( p_out ) return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_out );
1055 /****************************************************************************
1057 ****************************************************************************/
1058 static inline void video_timer_start( encoder_t * p_encoder )
1060 stats_TimerStart( p_encoder, "encoding video frame",
1061 STATS_TIMER_VIDEO_FRAME_ENCODING );
1064 static inline void video_timer_stop( encoder_t * p_encoder )
1066 stats_TimerStop( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1069 static inline void video_timer_close( encoder_t * p_encoder )
1071 stats_TimerDump( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1072 stats_TimerClean( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1075 static inline void audio_timer_start( encoder_t * p_encoder )
1077 stats_TimerStart( p_encoder, "encoding audio frame",
1078 STATS_TIMER_AUDIO_FRAME_ENCODING );
1081 static inline void audio_timer_stop( encoder_t * p_encoder )
1083 stats_TimerStop( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1086 static inline void audio_timer_close( encoder_t * p_encoder )
1088 stats_TimerDump( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1089 stats_TimerClean( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1092 /****************************************************************************
1093 * decoder reencoder part
1094 ****************************************************************************/
1096 static block_t *transcode_audio_alloc( filter_t *p_filter, int size )
1098 VLC_UNUSED( p_filter );
1099 return block_Alloc( size );
1102 static int transcode_audio_filter_allocation_init( filter_t *p_filter,
1106 p_filter->pf_audio_buffer_new = transcode_audio_alloc;
1110 static int transcode_audio_new( sout_stream_t *p_stream,
1111 sout_stream_id_t *id )
1113 sout_stream_sys_t *p_sys = p_stream->p_sys;
1114 es_format_t fmt_last;
1121 /* Initialization of decoder structures */
1122 id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1123 id->p_decoder->fmt_out.i_extra = 0;
1124 id->p_decoder->fmt_out.p_extra = 0;
1125 id->p_decoder->pf_decode_audio = NULL;
1126 id->p_decoder->pf_aout_buffer_new = audio_new_buffer;
1127 id->p_decoder->pf_aout_buffer_del = audio_del_buffer;
1128 /* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */
1130 id->p_decoder->p_module =
1131 module_Need( id->p_decoder, "decoder", "$codec", 0 );
1132 if( !id->p_decoder->p_module )
1134 msg_Err( p_stream, "cannot find audio decoder" );
1135 return VLC_EGENERIC;
1137 id->p_decoder->fmt_out.audio.i_bitspersample =
1138 aout_BitsPerSample( id->p_decoder->fmt_out.i_codec );
1139 fmt_last = id->p_decoder->fmt_out;
1140 /* Fix AAC SBR changing number of channels and sampling rate */
1141 if( !(id->p_decoder->fmt_in.i_codec == VLC_FOURCC('m','p','4','a') &&
1142 fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate &&
1143 fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels) )
1144 fmt_last.audio.i_rate = id->p_decoder->fmt_in.audio.i_rate;
1150 /* Initialization of encoder format structures */
1151 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1152 id->p_decoder->fmt_out.i_codec );
1153 id->p_encoder->fmt_in.audio.i_format = id->p_decoder->fmt_out.i_codec;
1155 id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;//id->p_encoder->fmt_out.audio.i_rate;
1156 id->p_encoder->fmt_in.audio.i_physical_channels =
1157 id->p_encoder->fmt_out.audio.i_physical_channels;
1158 id->p_encoder->fmt_in.audio.i_original_channels =
1159 id->p_encoder->fmt_out.audio.i_original_channels;
1160 id->p_encoder->fmt_in.audio.i_channels =
1161 id->p_encoder->fmt_out.audio.i_channels;
1162 id->p_encoder->fmt_in.audio.i_bitspersample =
1163 aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1165 id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1166 id->p_encoder->p_module =
1167 module_Need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1168 if( !id->p_encoder->p_module )
1170 msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)",
1171 p_sys->psz_aenc ? p_sys->psz_aenc : "any",
1172 (char *)&p_sys->i_acodec );
1173 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1174 id->p_decoder->p_module = NULL;
1175 return VLC_EGENERIC;
1177 id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1178 id->p_encoder->fmt_in.audio.i_bitspersample =
1179 aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1181 /* Init filter chain */
1182 id->p_f_chain = filter_chain_New( p_stream, "audio filter2", true,
1183 transcode_audio_filter_allocation_init, NULL, NULL );
1184 filter_chain_Reset( id->p_f_chain, &fmt_last, &id->p_encoder->fmt_in );
1186 /* Load conversion filters */
1187 if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels ||
1188 fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1190 /* We'll have to go through fl32 first */
1191 fmt_last.i_codec = fmt_last.audio.i_format = VLC_FOURCC('f','l','3','2');
1192 fmt_last.audio.i_bitspersample = aout_BitsPerSample( fmt_last.i_codec );
1193 filter_chain_AppendFilter( id->p_f_chain, NULL, NULL, NULL, &fmt_last );
1194 fmt_last = *filter_chain_GetFmtOut( id->p_f_chain );
1197 for( i = 0; i < 4; i++ )
1199 if( (fmt_last.audio.i_channels !=
1200 id->p_encoder->fmt_in.audio.i_channels) ||
1201 (fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate) ||
1202 (fmt_last.i_codec != id->p_encoder->fmt_in.i_codec) )
1204 filter_chain_AppendFilter( id->p_f_chain, NULL, NULL, &fmt_last, &id->p_encoder->fmt_in );
1205 fmt_last = *filter_chain_GetFmtOut( id->p_f_chain );
1209 /* Final checks to see if conversions were successful */
1210 if( fmt_last.i_codec != id->p_encoder->fmt_in.i_codec )
1212 msg_Err( p_stream, "no audio filter found (%4.4s->%4.4s)",
1213 (char *)&fmt_last.i_codec,
1214 (char *)&id->p_encoder->fmt_in.i_codec );
1215 transcode_audio_close( id );
1216 return VLC_EGENERIC;
1219 /* Load user specified audio filters now */
1220 if( p_sys->psz_af2 )
1222 id->p_uf_chain = filter_chain_New( p_stream, "audio filter2", false,
1223 transcode_audio_filter_allocation_init, NULL, NULL );
1224 filter_chain_Reset( id->p_uf_chain, &fmt_last, &id->p_encoder->fmt_in );
1225 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_af2 );
1228 if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels )
1231 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1232 id->p_encoder->p_module = NULL;
1234 /* This might work, but only if the encoder is restarted */
1235 id->p_encoder->fmt_in.audio.i_channels = fmt_last.audio.i_channels;
1236 id->p_encoder->fmt_out.audio.i_channels = fmt_last.audio.i_channels;
1238 id->p_encoder->fmt_in.audio.i_physical_channels =
1239 id->p_encoder->fmt_in.audio.i_original_channels =
1240 fmt_last.audio.i_physical_channels;
1241 id->p_encoder->fmt_out.audio.i_physical_channels =
1242 id->p_encoder->fmt_out.audio.i_original_channels =
1243 fmt_last.audio.i_physical_channels;
1245 msg_Dbg( p_stream, "number of audio channels for mixing changed, "
1246 "trying to reopen the encoder for mixing %i to %i channels",
1247 fmt_last.audio.i_channels,
1248 id->p_encoder->fmt_in.audio.i_channels );
1250 /* reload encoder */
1251 id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1252 id->p_encoder->p_module =
1253 module_Need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1254 if( !id->p_encoder->p_module )
1256 msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)",
1257 p_sys->psz_aenc ? p_sys->psz_aenc : "any",
1258 (char *)&p_sys->i_acodec );
1259 transcode_audio_close( id );
1260 return VLC_EGENERIC;
1262 id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1263 id->p_encoder->fmt_in.audio.i_bitspersample =
1264 aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1266 msg_Err( p_stream, "no audio filter found for mixing from"
1267 " %i to %i channels", fmt_last.audio.i_channels,
1268 id->p_encoder->fmt_in.audio.i_channels );
1270 transcode_audio_close( id );
1271 return VLC_EGENERIC;
1275 if( fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1277 msg_Err( p_stream, "no audio filter found for resampling from"
1278 " %iHz to %iHz", fmt_last.audio.i_rate,
1279 id->p_encoder->fmt_in.audio.i_rate );
1281 /* FIXME : this might work, but only if the encoder is restarted */
1282 id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;
1283 id->p_encoder->fmt_out.audio.i_rate = fmt_last.audio.i_rate;
1285 transcode_audio_close( id );
1286 return VLC_EGENERIC;
1290 /* FIXME: Hack for mp3 transcoding support */
1291 if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC( 'm','p','3',' ' ) )
1292 id->p_encoder->fmt_out.i_codec = VLC_FOURCC( 'm','p','g','a' );
1297 static void transcode_audio_close( sout_stream_id_t *id )
1299 audio_timer_close( id->p_encoder );
1302 if( id->p_decoder->p_module )
1303 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1304 id->p_decoder->p_module = NULL;
1307 if( id->p_encoder->p_module )
1308 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1309 id->p_encoder->p_module = NULL;
1313 filter_chain_Delete( id->p_f_chain );
1314 if( id->p_uf_chain )
1315 filter_chain_Delete( id->p_uf_chain );
1318 static int transcode_audio_process( sout_stream_t *p_stream,
1319 sout_stream_id_t *id,
1320 block_t *in, block_t **out )
1322 sout_stream_sys_t *p_sys = p_stream->p_sys;
1323 aout_buffer_t *p_audio_buf;
1324 block_t *p_block, *p_audio_block;
1327 while( (p_audio_buf = id->p_decoder->pf_decode_audio( id->p_decoder,
1330 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_AUDIO, 1 );
1331 if( p_sys->b_master_sync )
1333 mtime_t i_dts = date_Get( &id->interpolated_pts ) + 1;
1334 if ( p_audio_buf->start_date - i_dts > MASTER_SYNC_MAX_DRIFT
1335 || p_audio_buf->start_date - i_dts < -MASTER_SYNC_MAX_DRIFT )
1337 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1338 date_Set( &id->interpolated_pts, p_audio_buf->start_date );
1339 i_dts = p_audio_buf->start_date + 1;
1341 p_sys->i_master_drift = p_audio_buf->start_date - i_dts;
1342 date_Increment( &id->interpolated_pts, p_audio_buf->i_nb_samples );
1343 p_audio_buf->start_date -= p_sys->i_master_drift;
1344 p_audio_buf->end_date -= p_sys->i_master_drift;
1347 p_audio_block = p_audio_buf->p_sys;
1348 p_audio_block->i_buffer = p_audio_buf->i_nb_bytes;
1349 p_audio_block->i_dts = p_audio_block->i_pts =
1350 p_audio_buf->start_date;
1351 p_audio_block->i_length = p_audio_buf->end_date -
1352 p_audio_buf->start_date;
1353 p_audio_block->i_samples = p_audio_buf->i_nb_samples;
1355 /* Run filter chain */
1356 p_audio_block = filter_chain_AudioFilter( id->p_f_chain, p_audio_block );
1357 if( id->p_uf_chain )
1358 p_audio_block = filter_chain_AudioFilter( id->p_uf_chain, p_audio_block );
1359 assert( p_audio_block );
1361 p_audio_buf->p_buffer = p_audio_block->p_buffer;
1362 p_audio_buf->i_nb_bytes = p_audio_block->i_buffer;
1363 p_audio_buf->i_nb_samples = p_audio_block->i_samples;
1364 p_audio_buf->start_date = p_audio_block->i_dts;
1365 p_audio_buf->end_date = p_audio_block->i_dts + p_audio_block->i_length;
1367 audio_timer_start( id->p_encoder );
1368 p_block = id->p_encoder->pf_encode_audio( id->p_encoder, p_audio_buf );
1369 audio_timer_stop( id->p_encoder );
1371 block_ChainAppend( out, p_block );
1372 block_Release( p_audio_block );
1373 free( p_audio_buf );
1379 static void audio_release_buffer( aout_buffer_t *p_buffer )
1381 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1385 static aout_buffer_t *audio_new_buffer( decoder_t *p_dec, int i_samples )
1387 aout_buffer_t *p_buffer;
1391 if( p_dec->fmt_out.audio.i_bitspersample )
1393 i_size = i_samples * p_dec->fmt_out.audio.i_bitspersample / 8 *
1394 p_dec->fmt_out.audio.i_channels;
1396 else if( p_dec->fmt_out.audio.i_bytes_per_frame &&
1397 p_dec->fmt_out.audio.i_frame_length )
1399 i_size = i_samples * p_dec->fmt_out.audio.i_bytes_per_frame /
1400 p_dec->fmt_out.audio.i_frame_length;
1404 i_size = i_samples * 4 * p_dec->fmt_out.audio.i_channels;
1407 p_buffer = malloc( sizeof(aout_buffer_t) );
1408 if( !p_buffer ) return NULL;
1409 p_buffer->b_discontinuity = false;
1410 p_buffer->pf_release = audio_release_buffer;
1411 p_buffer->p_sys = p_block = block_New( p_dec, i_size );
1413 p_buffer->p_buffer = p_block->p_buffer;
1414 p_buffer->i_size = p_buffer->i_nb_bytes = p_block->i_buffer;
1415 p_buffer->i_nb_samples = i_samples;
1416 p_block->i_samples = i_samples;
1421 static void audio_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
1424 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1432 static int transcode_video_filter_allocation_init( filter_t *p_filter,
1435 sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_data;
1438 p_filter->pf_vout_buffer_new = video_new_buffer_filter;
1439 p_filter->pf_vout_buffer_del = video_del_buffer_filter;
1441 p_filter->p_owner = malloc( sizeof(filter_owner_sys_t) );
1442 if( !p_filter->p_owner )
1443 return VLC_EGENERIC;
1445 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1446 p_filter->p_owner->pp_pics[i] = 0;
1447 p_filter->p_owner->p_sys = p_sys;
1452 static void transcode_video_filter_allocation_clear( filter_t *p_filter )
1456 /* Clean-up pictures ring buffer */
1457 for( j = 0; j < PICTURE_RING_SIZE; j++ )
1459 if( p_filter->p_owner->pp_pics[j] )
1460 video_del_buffer( VLC_OBJECT(p_filter),
1461 p_filter->p_owner->pp_pics[j] );
1463 free( p_filter->p_owner );
1466 static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
1468 sout_stream_sys_t *p_sys = p_stream->p_sys;
1472 * Initialization of decoder structures
1474 id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1475 id->p_decoder->fmt_out.i_extra = 0;
1476 id->p_decoder->fmt_out.p_extra = 0;
1477 id->p_decoder->pf_decode_video = NULL;
1478 id->p_decoder->pf_get_cc = NULL;
1479 id->p_decoder->pf_get_cc = 0;
1480 id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
1481 id->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder;
1482 id->p_decoder->pf_picture_link = video_link_picture_decoder;
1483 id->p_decoder->pf_picture_unlink = video_unlink_picture_decoder;
1484 id->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) );
1485 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1486 id->p_decoder->p_owner->pp_pics[i] = 0;
1487 id->p_decoder->p_owner->p_sys = p_sys;
1488 /* id->p_decoder->p_cfg = p_sys->p_video_cfg; */
1490 id->p_decoder->p_module =
1491 module_Need( id->p_decoder, "decoder", "$codec", 0 );
1493 if( !id->p_decoder->p_module )
1495 msg_Err( p_stream, "cannot find video decoder" );
1496 return VLC_EGENERIC;
1501 * Because some info about the decoded input will only be available
1502 * once the first frame is decoded, we actually only test the availability
1503 * of the encoder here.
1506 /* Initialization of encoder format structures */
1507 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1508 id->p_decoder->fmt_out.i_codec );
1509 id->p_encoder->fmt_in.video.i_chroma = id->p_decoder->fmt_out.i_codec;
1511 /* The dimensions will be set properly later on.
1512 * Just put sensible values so we can test an encoder is available. */
1513 id->p_encoder->fmt_in.video.i_width =
1514 id->p_encoder->fmt_out.video.i_width ?:
1515 id->p_decoder->fmt_in.video.i_width ?: 16;
1516 id->p_encoder->fmt_in.video.i_height =
1517 id->p_encoder->fmt_out.video.i_height ?:
1518 id->p_decoder->fmt_in.video.i_height ?: 16;
1519 id->p_encoder->fmt_in.video.i_frame_rate = ENC_FRAMERATE;
1520 id->p_encoder->fmt_in.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1522 id->p_encoder->i_threads = p_sys->i_threads;
1523 id->p_encoder->p_cfg = p_sys->p_video_cfg;
1525 id->p_encoder->p_module =
1526 module_Need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1527 if( !id->p_encoder->p_module )
1529 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1530 p_sys->psz_venc ? p_sys->psz_venc : "any",
1531 (char *)&p_sys->i_vcodec );
1532 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1533 id->p_decoder->p_module = 0;
1534 return VLC_EGENERIC;
1537 /* Close the encoder.
1538 * We'll open it only when we have the first frame. */
1539 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1540 if( id->p_encoder->fmt_out.p_extra )
1542 free( id->p_encoder->fmt_out.p_extra );
1543 id->p_encoder->fmt_out.p_extra = NULL;
1544 id->p_encoder->fmt_out.i_extra = 0;
1546 id->p_encoder->p_module = NULL;
1548 if( p_sys->i_threads >= 1 )
1550 int i_priority = p_sys->b_high_priority ? VLC_THREAD_PRIORITY_OUTPUT :
1551 VLC_THREAD_PRIORITY_VIDEO;
1552 p_sys->id_video = id;
1553 vlc_mutex_init( &p_sys->lock_out );
1554 vlc_cond_init( p_stream, &p_sys->cond );
1555 memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) );
1556 p_sys->i_first_pic = 0;
1557 p_sys->i_last_pic = 0;
1558 p_sys->p_buffers = NULL;
1559 p_sys->b_die = p_sys->b_error = 0;
1560 if( vlc_thread_create( p_sys, "encoder", EncoderThread, i_priority,
1563 msg_Err( p_stream, "cannot spawn encoder thread" );
1564 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1565 id->p_decoder->p_module = 0;
1566 return VLC_EGENERIC;
1573 static void transcode_video_encoder_init( sout_stream_t *p_stream,
1574 sout_stream_id_t *id )
1576 sout_stream_sys_t *p_sys = p_stream->p_sys;
1578 /* Calculate scaling
1579 * width/height of source */
1580 int i_src_width = id->p_decoder->fmt_out.video.i_width;
1581 int i_src_height = id->p_decoder->fmt_out.video.i_height;
1583 /* with/height scaling */
1584 float f_scale_width = 1;
1585 float f_scale_height = 1;
1587 /* width/height of output stream */
1592 float f_aspect = (float)id->p_decoder->fmt_out.video.i_aspect /
1595 msg_Dbg( p_stream, "decoder aspect is %i:%i",
1596 id->p_decoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1598 /* Change f_aspect from source frame to source pixel */
1599 f_aspect = f_aspect * i_src_height / i_src_width;
1600 msg_Dbg( p_stream, "source pixel aspect is %f:1", f_aspect );
1602 /* Calculate scaling factor for specified parameters */
1603 if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1604 id->p_encoder->fmt_out.video.i_height <= 0 && p_sys->f_scale )
1606 /* Global scaling. Make sure width will remain a factor of 16 */
1609 int i_new_width = i_src_width * p_sys->f_scale;
1611 if( i_new_width % 16 <= 7 && i_new_width >= 16 )
1612 i_new_width -= i_new_width % 16;
1614 i_new_width += 16 - i_new_width % 16;
1616 f_real_scale = (float)( i_new_width ) / (float) i_src_width;
1618 i_new_height = __MAX( 16, i_src_height * (float)f_real_scale );
1620 f_scale_width = f_real_scale;
1621 f_scale_height = (float) i_new_height / (float) i_src_height;
1623 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1624 id->p_encoder->fmt_out.video.i_height <= 0 )
1626 /* Only width specified */
1627 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1628 f_scale_height = f_scale_width;
1630 else if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1631 id->p_encoder->fmt_out.video.i_height > 0 )
1633 /* Only height specified */
1634 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1635 f_scale_width = f_scale_height;
1637 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1638 id->p_encoder->fmt_out.video.i_height > 0 )
1640 /* Width and height specified */
1641 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1642 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1645 /* check maxwidth and maxheight
1647 if( p_sys->i_maxwidth && f_scale_width > (float)p_sys->i_maxwidth /
1650 f_scale_width = (float)p_sys->i_maxwidth / i_src_width;
1653 if( p_sys->i_maxheight && f_scale_height > (float)p_sys->i_maxheight /
1656 f_scale_height = (float)p_sys->i_maxheight / i_src_height;
1660 /* Change aspect ratio from source pixel to scaled pixel */
1661 f_aspect = f_aspect * f_scale_height / f_scale_width;
1662 msg_Dbg( p_stream, "scaled pixel aspect is %f:1", f_aspect );
1664 /* f_scale_width and f_scale_height are now final */
1665 /* Calculate width, height from scaling
1666 * Make sure its multiple of 2
1668 i_dst_width = 2 * (int)(f_scale_width*i_src_width/2+0.5);
1669 i_dst_height = 2 * (int)(f_scale_height*i_src_height/2+0.5);
1671 /* Change aspect ratio from scaled pixel to output frame */
1672 f_aspect = f_aspect * i_dst_width / i_dst_height;
1674 /* Store calculated values */
1675 id->p_encoder->fmt_out.video.i_width = i_dst_width;
1676 id->p_encoder->fmt_out.video.i_height = i_dst_height;
1678 id->p_encoder->fmt_in.video.i_width = i_dst_width;
1679 id->p_encoder->fmt_in.video.i_height = i_dst_height;
1681 msg_Dbg( p_stream, "source %ix%i, destination %ix%i",
1682 i_src_width, i_src_height,
1683 i_dst_width, i_dst_height
1686 /* Handle frame rate conversion */
1687 if( !id->p_encoder->fmt_out.video.i_frame_rate ||
1688 !id->p_encoder->fmt_out.video.i_frame_rate_base )
1690 if( id->p_decoder->fmt_out.video.i_frame_rate &&
1691 id->p_decoder->fmt_out.video.i_frame_rate_base )
1693 id->p_encoder->fmt_out.video.i_frame_rate =
1694 id->p_decoder->fmt_out.video.i_frame_rate;
1695 id->p_encoder->fmt_out.video.i_frame_rate_base =
1696 id->p_decoder->fmt_out.video.i_frame_rate_base;
1700 /* Pick a sensible default value */
1701 id->p_encoder->fmt_out.video.i_frame_rate = ENC_FRAMERATE;
1702 id->p_encoder->fmt_out.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1706 id->p_encoder->fmt_in.video.i_frame_rate =
1707 id->p_encoder->fmt_out.video.i_frame_rate;
1708 id->p_encoder->fmt_in.video.i_frame_rate_base =
1709 id->p_encoder->fmt_out.video.i_frame_rate_base;
1711 date_Init( &id->interpolated_pts,
1712 id->p_encoder->fmt_out.video.i_frame_rate,
1713 id->p_encoder->fmt_out.video.i_frame_rate_base );
1715 /* Check whether a particular aspect ratio was requested */
1716 if( !id->p_encoder->fmt_out.video.i_aspect )
1718 id->p_encoder->fmt_out.video.i_aspect =
1719 (int)( f_aspect * VOUT_ASPECT_FACTOR + 0.5 );
1721 id->p_encoder->fmt_in.video.i_aspect =
1722 id->p_encoder->fmt_out.video.i_aspect;
1724 msg_Dbg( p_stream, "encoder aspect is %i:%i",
1725 id->p_encoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1727 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1730 static int transcode_video_encoder_open( sout_stream_t *p_stream,
1731 sout_stream_id_t *id )
1733 sout_stream_sys_t *p_sys = p_stream->p_sys;
1736 msg_Dbg( p_stream, "destination (after video filters) %ix%i",
1737 id->p_encoder->fmt_in.video.i_width,
1738 id->p_encoder->fmt_in.video.i_height );
1740 id->p_encoder->p_module =
1741 module_Need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1742 if( !id->p_encoder->p_module )
1744 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1745 p_sys->psz_venc ? p_sys->psz_venc : "any",
1746 (char *)&p_sys->i_vcodec );
1747 return VLC_EGENERIC;
1750 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1752 /* Hack for mp2v/mp1v transcoding support */
1753 if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','1','v') ||
1754 id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','2','v') )
1756 id->p_encoder->fmt_out.i_codec = VLC_FOURCC('m','p','g','v');
1759 id->id = p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out,
1760 &id->p_encoder->fmt_out );
1763 msg_Err( p_stream, "cannot add this stream" );
1764 return VLC_EGENERIC;
1770 static void transcode_video_close( sout_stream_t *p_stream,
1771 sout_stream_id_t *id )
1775 if( p_stream->p_sys->i_threads >= 1 )
1777 vlc_mutex_lock( &p_stream->p_sys->lock_out );
1778 vlc_object_kill( p_stream->p_sys );
1779 vlc_cond_signal( &p_stream->p_sys->cond );
1780 vlc_mutex_unlock( &p_stream->p_sys->lock_out );
1781 vlc_thread_join( p_stream->p_sys );
1782 vlc_mutex_destroy( &p_stream->p_sys->lock_out );
1783 vlc_cond_destroy( &p_stream->p_sys->cond );
1786 video_timer_close( id->p_encoder );
1789 if( id->p_decoder->p_module )
1790 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1792 if( id->p_decoder->p_owner )
1794 /* Clean-up pictures ring buffer */
1795 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1797 if( id->p_decoder->p_owner->pp_pics[i] )
1798 video_del_buffer( VLC_OBJECT(id->p_decoder),
1799 id->p_decoder->p_owner->pp_pics[i] );
1801 free( id->p_decoder->p_owner );
1805 if( id->p_encoder->p_module )
1806 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1810 filter_chain_Delete( id->p_f_chain );
1811 if( id->p_uf_chain )
1812 filter_chain_Delete( id->p_uf_chain );
1815 static int transcode_video_process( sout_stream_t *p_stream,
1816 sout_stream_id_t *id,
1817 block_t *in, block_t **out )
1819 sout_stream_sys_t *p_sys = p_stream->p_sys;
1820 int i_duplicate = 1;
1821 picture_t *p_pic, *p_pic2 = NULL;
1824 while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
1826 subpicture_t *p_subpic = NULL;
1828 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_VIDEO, 1 );
1830 if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )
1832 mtime_t current_date = mdate();
1833 if( current_date + 50000 > p_pic->date )
1835 msg_Dbg( p_stream, "late picture skipped (%"PRId64")",
1836 current_date + 50000 - p_pic->date );
1837 p_pic->pf_release( p_pic );
1842 if( p_sys->b_master_sync )
1844 mtime_t i_video_drift;
1845 mtime_t i_master_drift = p_sys->i_master_drift;
1848 i_pts = date_Get( &id->interpolated_pts ) + 1;
1849 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1850 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
1852 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1853 date_Set( &id->interpolated_pts, p_pic->date );
1854 i_pts = p_pic->date + 1;
1856 i_video_drift = p_pic->date - i_pts;
1859 /* Set the pts of the frame being encoded */
1860 p_pic->date = i_pts;
1862 if( i_video_drift < (i_master_drift - 50000) )
1865 msg_Dbg( p_stream, "dropping frame (%i)",
1866 (int)(i_video_drift - i_master_drift) );
1868 p_pic->pf_release( p_pic );
1871 else if( i_video_drift > (i_master_drift + 50000) )
1874 msg_Dbg( p_stream, "adding frame (%i)",
1875 (int)(i_video_drift - i_master_drift) );
1881 if( !id->p_encoder->p_module )
1883 transcode_video_encoder_init( p_stream, id );
1885 id->p_f_chain = filter_chain_New( p_stream, "video filter2",
1887 transcode_video_filter_allocation_init,
1888 transcode_video_filter_allocation_clear,
1892 if( p_stream->p_sys->b_deinterlace )
1894 filter_chain_AppendFilter( id->p_f_chain,
1895 p_sys->psz_deinterlace,
1896 p_sys->p_deinterlace_cfg,
1897 &id->p_decoder->fmt_out,
1898 &id->p_decoder->fmt_out );
1901 /* Take care of the scaling and chroma conversions */
1902 if( ( id->p_decoder->fmt_out.video.i_chroma !=
1903 id->p_encoder->fmt_in.video.i_chroma ) ||
1904 ( id->p_decoder->fmt_out.video.i_width !=
1905 id->p_encoder->fmt_in.video.i_width ) ||
1906 ( id->p_decoder->fmt_out.video.i_height !=
1907 id->p_encoder->fmt_in.video.i_height ) )
1909 filter_chain_AppendFilter( id->p_f_chain,
1911 &id->p_decoder->fmt_out,
1912 &id->p_encoder->fmt_in );
1915 if( p_sys->psz_vf2 )
1917 const es_format_t *p_fmt_out;
1918 id->p_uf_chain = filter_chain_New( p_stream, "video filter2",
1920 transcode_video_filter_allocation_init,
1921 transcode_video_filter_allocation_clear,
1923 filter_chain_Reset( id->p_uf_chain, &id->p_decoder->fmt_out,
1924 &id->p_encoder->fmt_in );
1925 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_vf2 );
1926 p_fmt_out = filter_chain_GetFmtOut( id->p_uf_chain );
1927 es_format_Copy( &id->p_encoder->fmt_in, p_fmt_out );
1928 id->p_encoder->fmt_out.video.i_width =
1929 id->p_encoder->fmt_in.video.i_width;
1930 id->p_encoder->fmt_out.video.i_height =
1931 id->p_encoder->fmt_in.video.i_height;
1934 if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS )
1936 filter_chain_Delete( id->p_f_chain );
1937 if( id->p_uf_chain )
1938 filter_chain_Delete( id->p_uf_chain );
1939 p_pic->pf_release( p_pic );
1940 transcode_video_close( p_stream, id );
1941 id->b_transcode = false;
1942 return VLC_EGENERIC;
1946 /* Run filter chain */
1948 p_pic = filter_chain_VideoFilter( id->p_f_chain, p_pic );
1954 /* Check if we have a subpicture to overlay */
1957 p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date,
1958 false /* Fixme: check if stream is paused */ );
1959 /* TODO: get another pic */
1962 /* Overlay subpicture */
1965 int i_scale_width, i_scale_height;
1968 i_scale_width = id->p_encoder->fmt_in.video.i_width * 1000 /
1969 id->p_decoder->fmt_out.video.i_width;
1970 i_scale_height = id->p_encoder->fmt_in.video.i_height * 1000 /
1971 id->p_decoder->fmt_out.video.i_height;
1973 if( p_pic->i_refcount && !filter_chain_GetLength( id->p_f_chain ) )
1975 /* We can't modify the picture, we need to duplicate it */
1976 picture_t *p_tmp = video_new_buffer_decoder( id->p_decoder );
1979 vout_CopyPicture( p_stream, p_tmp, p_pic );
1980 p_pic->pf_release( p_pic );
1985 fmt = filter_chain_GetFmtOut( id->p_f_chain )->video;
1987 /* FIXME (shouldn't have to be done here) */
1988 fmt.i_sar_num = fmt.i_aspect * fmt.i_height / fmt.i_width;
1989 fmt.i_sar_den = VOUT_ASPECT_FACTOR;
1991 spu_RenderSubpictures( p_sys->p_spu, &fmt, p_pic, p_pic, p_subpic,
1992 i_scale_width, i_scale_height );
1995 /* Run user specified filter chain */
1996 if( id->p_uf_chain )
1997 p_pic = filter_chain_VideoFilter( id->p_uf_chain, p_pic );
1999 if( p_sys->i_threads == 0 )
2003 video_timer_start( id->p_encoder );
2004 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2005 video_timer_stop( id->p_encoder );
2007 block_ChainAppend( out, p_block );
2010 if( p_sys->b_master_sync )
2012 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
2013 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
2014 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
2016 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2017 date_Set( &id->interpolated_pts, p_pic->date );
2018 i_pts = p_pic->date + 1;
2020 date_Increment( &id->interpolated_pts, 1 );
2023 if( p_sys->b_master_sync && i_duplicate > 1 )
2025 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
2026 if( (p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT)
2027 || ((p_pic->date - i_pts) < -MASTER_SYNC_MAX_DRIFT) )
2029 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2030 date_Set( &id->interpolated_pts, p_pic->date );
2031 i_pts = p_pic->date + 1;
2033 date_Increment( &id->interpolated_pts, 1 );
2035 if( p_sys->i_threads >= 1 )
2037 /* We can't modify the picture, we need to duplicate it */
2038 p_pic2 = video_new_buffer_decoder( id->p_decoder );
2039 if( p_pic2 != NULL )
2041 vout_CopyPicture( p_stream, p_pic2, p_pic );
2042 p_pic2->date = i_pts;
2048 p_pic->date = i_pts;
2049 video_timer_start( id->p_encoder );
2050 p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);
2051 video_timer_stop( id->p_encoder );
2052 block_ChainAppend( out, p_block );
2056 if( p_sys->i_threads == 0 )
2058 p_pic->pf_release( p_pic );
2062 vlc_mutex_lock( &p_sys->lock_out );
2063 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
2064 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2065 *out = p_sys->p_buffers;
2066 p_sys->p_buffers = NULL;
2067 if( p_pic2 != NULL )
2069 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic2;
2070 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2072 vlc_cond_signal( &p_sys->cond );
2073 vlc_mutex_unlock( &p_sys->lock_out );
2080 static int EncoderThread( sout_stream_sys_t *p_sys )
2082 sout_stream_id_t *id = p_sys->id_video;
2085 while( !p_sys->b_die && !p_sys->b_error )
2089 vlc_mutex_lock( &p_sys->lock_out );
2090 while( p_sys->i_last_pic == p_sys->i_first_pic )
2092 vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );
2093 if( p_sys->b_die || p_sys->b_error ) break;
2095 if( p_sys->b_die || p_sys->b_error )
2097 vlc_mutex_unlock( &p_sys->lock_out );
2101 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2102 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2103 vlc_mutex_unlock( &p_sys->lock_out );
2105 video_timer_start( id->p_encoder );
2106 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2107 video_timer_stop( id->p_encoder );
2109 vlc_mutex_lock( &p_sys->lock_out );
2110 block_ChainAppend( &p_sys->p_buffers, p_block );
2112 vlc_mutex_unlock( &p_sys->lock_out );
2113 p_pic->pf_release( p_pic );
2116 while( p_sys->i_last_pic != p_sys->i_first_pic )
2118 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2119 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2120 p_pic->pf_release( p_pic );
2122 block_ChainRelease( p_sys->p_buffers );
2127 struct picture_sys_t
2129 vlc_object_t *p_owner;
2132 static void video_release_buffer( picture_t *p_pic )
2134 if( p_pic && !p_pic->i_refcount && p_pic->pf_release && p_pic->p_sys )
2136 video_del_buffer_decoder( (decoder_t *)p_pic->p_sys->p_owner, p_pic );
2138 else if( p_pic && p_pic->i_refcount > 0 ) p_pic->i_refcount--;
2141 static picture_t *video_new_buffer( vlc_object_t *p_this, picture_t **pp_ring,
2142 sout_stream_sys_t *p_sys )
2144 decoder_t *p_dec = (decoder_t *)p_this;
2148 /* Find an empty space in the picture ring buffer */
2149 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2151 if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2153 pp_ring[i]->i_status = RESERVED_PICTURE;
2157 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2159 if( pp_ring[i] == 0 ) break;
2162 if( i == PICTURE_RING_SIZE && p_sys->i_threads >= 1 )
2164 int i_first_pic = p_sys->i_first_pic;
2166 if( p_sys->i_first_pic != p_sys->i_last_pic )
2168 /* Encoder still has stuff to encode, wait to clear-up the list */
2169 while( p_sys->i_first_pic == i_first_pic )
2173 /* Find an empty space in the picture ring buffer */
2174 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2176 if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2178 pp_ring[i]->i_status = RESERVED_PICTURE;
2182 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2184 if( pp_ring[i] == 0 ) break;
2188 if( i == PICTURE_RING_SIZE )
2190 msg_Err( p_this, "decoder/filter is leaking pictures, "
2191 "resetting its ring buffer" );
2193 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2195 pp_ring[i]->pf_release( pp_ring[i] );
2201 p_pic = malloc( sizeof(picture_t) );
2202 if( !p_pic ) return NULL;
2203 p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
2204 vout_AllocatePicture( VLC_OBJECT(p_dec), p_pic,
2205 p_dec->fmt_out.video.i_chroma,
2206 p_dec->fmt_out.video.i_width,
2207 p_dec->fmt_out.video.i_height,
2208 p_dec->fmt_out.video.i_aspect );
2210 if( !p_pic->i_planes )
2216 p_pic->pf_release = video_release_buffer;
2217 p_pic->p_sys = malloc( sizeof(picture_sys_t) );
2224 p_pic->p_sys->p_owner = p_this;
2225 p_pic->i_status = RESERVED_PICTURE;
2231 static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
2233 return video_new_buffer( VLC_OBJECT(p_dec),
2234 p_dec->p_owner->pp_pics, p_dec->p_owner->p_sys );
2237 static picture_t *video_new_buffer_filter( filter_t *p_filter )
2239 return video_new_buffer( VLC_OBJECT(p_filter),
2240 p_filter->p_owner->pp_pics,
2241 p_filter->p_owner->p_sys );
2244 static void video_del_buffer( vlc_object_t *p_this, picture_t *p_pic )
2249 free( p_pic->p_data_orig );
2250 free( p_pic->p_sys );
2255 static void video_del_buffer_decoder( decoder_t *p_decoder, picture_t *p_pic )
2257 VLC_UNUSED(p_decoder);
2258 p_pic->i_refcount = 0;
2259 p_pic->i_status = DESTROYED_PICTURE;
2262 static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic )
2264 VLC_UNUSED(p_filter);
2265 p_pic->i_refcount = 0;
2266 p_pic->i_status = DESTROYED_PICTURE;
2269 static void video_link_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2272 p_pic->i_refcount++;
2275 static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2278 video_release_buffer( p_pic );
2284 static subpicture_t *spu_new_buffer( decoder_t * );
2285 static void spu_del_buffer( decoder_t *, subpicture_t * );
2287 static int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2289 sout_stream_sys_t *p_sys = p_stream->p_sys;
2295 /* Initialization of decoder structures */
2296 id->p_decoder->pf_decode_sub = NULL;
2297 id->p_decoder->pf_spu_buffer_new = spu_new_buffer;
2298 id->p_decoder->pf_spu_buffer_del = spu_del_buffer;
2299 id->p_decoder->p_owner = (decoder_owner_sys_t *)p_stream;
2300 /* id->p_decoder->p_cfg = p_sys->p_spu_cfg; */
2302 id->p_decoder->p_module =
2303 module_Need( id->p_decoder, "decoder", "$codec", 0 );
2305 if( !id->p_decoder->p_module )
2307 msg_Err( p_stream, "cannot find spu decoder" );
2308 return VLC_EGENERIC;
2311 if( !p_sys->b_soverlay )
2314 /* Initialization of encoder format structures */
2315 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2316 id->p_decoder->fmt_in.i_codec );
2318 id->p_encoder->p_cfg = p_sys->p_spu_cfg;
2320 id->p_encoder->p_module =
2321 module_Need( id->p_encoder, "encoder", p_sys->psz_senc, true );
2323 if( !id->p_encoder->p_module )
2325 module_Unneed( id->p_decoder, id->p_decoder->p_module );
2326 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_senc );
2327 return VLC_EGENERIC;
2333 p_sys->p_spu = spu_Create( p_stream );
2334 spu_Init( p_sys->p_spu );
2340 static void transcode_spu_close( sout_stream_id_t *id)
2343 if( id->p_decoder->p_module )
2344 module_Unneed( id->p_decoder, id->p_decoder->p_module );
2347 if( id->p_encoder->p_module )
2348 module_Unneed( id->p_encoder, id->p_encoder->p_module );
2351 static int transcode_spu_process( sout_stream_t *p_stream,
2352 sout_stream_id_t *id,
2353 block_t *in, block_t **out )
2355 sout_stream_sys_t *p_sys = p_stream->p_sys;
2356 subpicture_t *p_subpic;
2359 p_subpic = id->p_decoder->pf_decode_sub( id->p_decoder, &in );
2361 return VLC_EGENERIC;
2363 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_SUBTITLE, 1 );
2365 if( p_sys->b_master_sync && p_sys->i_master_drift )
2367 p_subpic->i_start -= p_sys->i_master_drift;
2368 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2371 if( p_sys->b_soverlay )
2373 spu_DisplaySubpicture( p_sys->p_spu, p_subpic );
2379 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2380 spu_del_buffer( id->p_decoder, p_subpic );
2383 block_ChainAppend( out, p_block );
2388 return VLC_EGENERIC;
2391 static subpicture_t *spu_new_buffer( decoder_t *p_dec )
2393 sout_stream_t *p_stream = (sout_stream_t *)p_dec->p_owner;
2394 return spu_CreateSubpicture( p_stream->p_sys->p_spu );
2397 static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
2399 sout_stream_t *p_stream = (sout_stream_t *)p_dec->p_owner;
2400 spu_DestroySubpicture( p_stream->p_sys->p_spu, p_subpic );
2406 static int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2408 sout_stream_sys_t *p_sys = p_stream->p_sys;
2410 id->p_decoder->fmt_in.i_cat = SPU_ES;
2411 id->p_encoder->fmt_out.psz_language = strdup( "osd" );
2413 if( p_sys->i_osdcodec != 0 || p_sys->psz_osdenc )
2415 msg_Dbg( p_stream, "creating osdmenu transcoding from fcc=`%4.4s' "
2416 "to fcc=`%4.4s'", (char*)&id->p_encoder->fmt_out.i_codec,
2417 (char*)&p_sys->i_osdcodec );
2419 /* Complete destination format */
2420 id->p_encoder->fmt_out.i_codec = p_sys->i_osdcodec;
2423 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2424 VLC_FOURCC('Y','U','V','A') );
2425 id->p_encoder->fmt_in.psz_language = strdup( "osd" );
2427 id->p_encoder->p_cfg = p_sys->p_osd_cfg;
2429 id->p_encoder->p_module =
2430 module_Need( id->p_encoder, "encoder", p_sys->psz_osdenc, true );
2432 if( !id->p_encoder->p_module )
2434 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_osdenc );
2438 /* open output stream */
2439 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_encoder->fmt_out );
2440 id->b_transcode = true;
2442 if( !id->id ) goto error;
2446 msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
2447 (char*)&id->p_decoder->fmt_out.i_codec );
2448 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_decoder->fmt_out );
2449 id->b_transcode = false;
2451 if( !id->id ) goto error;
2456 p_sys->p_spu = spu_Create( p_stream );
2457 spu_Init( p_sys->p_spu );
2463 msg_Err( p_stream, "starting osd encoding thread failed" );
2464 if( id->p_encoder->p_module )
2465 module_Unneed( id->p_encoder, id->p_encoder->p_module );
2466 p_sys->b_osd = false;
2467 return VLC_EGENERIC;
2470 static void transcode_osd_close( sout_stream_t *p_stream, sout_stream_id_t *id)
2472 sout_stream_sys_t *p_sys = p_stream->p_sys;
2477 if( id->p_encoder->p_module )
2478 module_Unneed( id->p_encoder, id->p_encoder->p_module );
2480 p_sys->b_osd = false;
2483 static int transcode_osd_process( sout_stream_t *p_stream,
2484 sout_stream_id_t *id,
2485 block_t *in, block_t **out )
2487 sout_stream_sys_t *p_sys = p_stream->p_sys;
2488 subpicture_t *p_subpic = NULL;
2490 /* Check if we have a subpicture to send */
2491 if( p_sys->p_spu && in->i_dts > 0)
2493 p_subpic = spu_SortSubpictures( p_sys->p_spu, in->i_dts, false );
2497 msg_Warn( p_stream, "spu channel not initialized, doing it now" );
2500 p_sys->p_spu = spu_Create( p_stream );
2501 spu_Init( p_sys->p_spu );
2507 block_t *p_block = NULL;
2509 if( p_sys->b_master_sync && p_sys->i_master_drift )
2511 p_subpic->i_start -= p_sys->i_master_drift;
2512 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2515 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2516 spu_DestroySubpicture( p_sys->p_spu, p_subpic );
2519 p_block->i_dts = p_block->i_pts = in->i_dts;
2520 block_ChainAppend( out, p_block );
2524 return VLC_EGENERIC;