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 int transcode_video_encoder_open( sout_stream_t *, sout_stream_id_t *);
266 static int transcode_video_process( sout_stream_t *, sout_stream_id_t *,
267 block_t *, block_t ** );
269 static void video_del_buffer( vlc_object_t *, picture_t * );
270 static picture_t *video_new_buffer_decoder( decoder_t * );
271 static void video_del_buffer_decoder( decoder_t *, picture_t * );
272 static void video_link_picture_decoder( decoder_t *, picture_t * );
273 static void video_unlink_picture_decoder( decoder_t *, picture_t * );
274 static picture_t *video_new_buffer_filter( filter_t * );
275 static void video_del_buffer_filter( filter_t *, picture_t * );
277 static int transcode_spu_new ( sout_stream_t *, sout_stream_id_t * );
278 static void transcode_spu_close ( sout_stream_id_t * );
279 static int transcode_spu_process( sout_stream_t *, sout_stream_id_t *,
280 block_t *, block_t ** );
282 static int transcode_osd_new ( sout_stream_t *, sout_stream_id_t * );
283 static void transcode_osd_close ( sout_stream_t *, sout_stream_id_t * );
284 static int transcode_osd_process( sout_stream_t *, sout_stream_id_t *,
285 block_t *, block_t ** );
287 static int EncoderThread( struct sout_stream_sys_t * p_sys );
289 static int pi_channels_maps[6] =
292 AOUT_CHAN_CENTER, AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
293 AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
294 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
295 | AOUT_CHAN_REARRIGHT,
296 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
297 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
300 #define PICTURE_RING_SIZE 64
301 #define SUBPICTURE_RING_SIZE 20
303 #define ENC_FRAMERATE (25 * 1000 + .5)
304 #define ENC_FRAMERATE_BASE 1000
306 struct sout_stream_sys_t
310 sout_stream_t *p_out;
311 sout_stream_id_t *id_video;
313 vlc_mutex_t lock_out;
315 picture_t * pp_pics[PICTURE_RING_SIZE];
316 int i_first_pic, i_last_pic;
319 vlc_fourcc_t i_acodec; /* codec audio (0 if not transcode) */
321 config_chain_t *p_audio_cfg;
322 uint32_t i_sample_rate;
329 vlc_fourcc_t i_vcodec; /* codec video (0 if not transcode) */
331 config_chain_t *p_video_cfg;
335 unsigned int i_width, i_maxwidth;
336 unsigned int i_height, i_maxheight;
338 char *psz_deinterlace;
339 config_chain_t *p_deinterlace_cfg;
341 bool b_high_priority;
347 vlc_fourcc_t i_scodec; /* codec spu (0 if not transcode) */
350 config_chain_t *p_spu_cfg;
354 vlc_fourcc_t i_osdcodec; /* codec osd menu (0 if not transcode) */
356 config_chain_t *p_osd_cfg;
357 bool b_osd; /* true when osd es is registered */
361 mtime_t i_master_drift;
364 struct decoder_owner_sys_t
366 picture_t *pp_pics[PICTURE_RING_SIZE];
367 sout_stream_sys_t *p_sys;
369 struct filter_owner_sys_t
371 picture_t *pp_pics[PICTURE_RING_SIZE];
372 sout_stream_sys_t *p_sys;
375 /*****************************************************************************
377 *****************************************************************************/
378 static int Open( vlc_object_t *p_this )
380 sout_stream_t *p_stream = (sout_stream_t*)p_this;
381 sout_stream_sys_t *p_sys;
384 p_sys = vlc_object_create( p_this, sizeof( sout_stream_sys_t ) );
386 p_sys->p_out = sout_StreamNew( p_stream->p_sout, p_stream->psz_next );
389 msg_Err( p_stream, "cannot create chain" );
390 vlc_object_release( p_sys );
394 p_sys->i_master_drift = 0;
396 config_ChainParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options,
399 /* Audio transcoding parameters */
400 var_Get( p_stream, SOUT_CFG_PREFIX "aenc", &val );
401 p_sys->psz_aenc = NULL;
402 p_sys->p_audio_cfg = NULL;
403 if( val.psz_string && *val.psz_string )
406 psz_next = config_ChainCreate( &p_sys->psz_aenc, &p_sys->p_audio_cfg,
410 free( val.psz_string );
412 var_Get( p_stream, SOUT_CFG_PREFIX "acodec", &val );
414 if( val.psz_string && *val.psz_string )
417 memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) );
418 p_sys->i_acodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
420 free( val.psz_string );
422 var_Get( p_stream, SOUT_CFG_PREFIX "ab", &val );
423 p_sys->i_abitrate = val.i_int;
424 if( p_sys->i_abitrate < 4000 ) p_sys->i_abitrate *= 1000;
426 var_Get( p_stream, SOUT_CFG_PREFIX "samplerate", &val );
427 p_sys->i_sample_rate = val.i_int;
429 var_Get( p_stream, SOUT_CFG_PREFIX "channels", &val );
430 p_sys->i_channels = val.i_int;
432 if( p_sys->i_acodec )
434 if( p_sys->i_acodec == VLC_FOURCC('m','p','3',0) &&
435 p_sys->i_channels > 2 )
437 msg_Warn( p_stream, "%d channels invalid for mp3, forcing to 2",
439 p_sys->i_channels = 2;
441 msg_Dbg( p_stream, "codec audio=%4.4s %dHz %d channels %dKb/s",
442 (char *)&p_sys->i_acodec, p_sys->i_sample_rate,
443 p_sys->i_channels, p_sys->i_abitrate / 1000 );
446 var_Get( p_stream, SOUT_CFG_PREFIX "afilter", &val );
447 if( val.psz_string && *val.psz_string )
448 p_sys->psz_af2 = val.psz_string;
451 free( val.psz_string );
452 p_sys->psz_af2 = NULL;
455 /* Video transcoding parameters */
456 var_Get( p_stream, SOUT_CFG_PREFIX "venc", &val );
457 p_sys->psz_venc = NULL;
458 p_sys->p_video_cfg = NULL;
459 if( val.psz_string && *val.psz_string )
462 psz_next = config_ChainCreate( &p_sys->psz_venc, &p_sys->p_video_cfg,
466 free( val.psz_string );
468 var_Get( p_stream, SOUT_CFG_PREFIX "vcodec", &val );
470 if( val.psz_string && *val.psz_string )
473 memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) );
474 p_sys->i_vcodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
476 free( val.psz_string );
478 var_Get( p_stream, SOUT_CFG_PREFIX "vb", &val );
479 p_sys->i_vbitrate = val.i_int;
480 if( p_sys->i_vbitrate < 16000 ) p_sys->i_vbitrate *= 1000;
482 var_Get( p_stream, SOUT_CFG_PREFIX "scale", &val );
483 p_sys->f_scale = val.f_float;
485 var_Get( p_stream, SOUT_CFG_PREFIX "fps", &val );
486 p_sys->f_fps = val.f_float;
488 var_Get( p_stream, SOUT_CFG_PREFIX "hurry-up", &val );
489 p_sys->b_hurry_up = val.b_bool;
491 var_Get( p_stream, SOUT_CFG_PREFIX "width", &val );
492 p_sys->i_width = val.i_int;
494 var_Get( p_stream, SOUT_CFG_PREFIX "height", &val );
495 p_sys->i_height = val.i_int;
497 var_Get( p_stream, SOUT_CFG_PREFIX "maxwidth", &val );
498 p_sys->i_maxwidth = val.i_int;
500 var_Get( p_stream, SOUT_CFG_PREFIX "maxheight", &val );
501 p_sys->i_maxheight = val.i_int;
503 var_Get( p_stream, SOUT_CFG_PREFIX "vfilter", &val );
504 if( val.psz_string && *val.psz_string )
505 p_sys->psz_vf2 = val.psz_string;
508 free( val.psz_string );
509 p_sys->psz_vf2 = NULL;
512 var_Get( p_stream, SOUT_CFG_PREFIX "deinterlace", &val );
513 p_sys->b_deinterlace = val.b_bool;
515 var_Get( p_stream, SOUT_CFG_PREFIX "deinterlace-module", &val );
516 p_sys->psz_deinterlace = NULL;
517 p_sys->p_deinterlace_cfg = NULL;
518 if( val.psz_string && *val.psz_string )
521 psz_next = config_ChainCreate( &p_sys->psz_deinterlace,
522 &p_sys->p_deinterlace_cfg,
526 free( val.psz_string );
528 var_Get( p_stream, SOUT_CFG_PREFIX "threads", &val );
529 p_sys->i_threads = val.i_int;
530 var_Get( p_stream, SOUT_CFG_PREFIX "high-priority", &val );
531 p_sys->b_high_priority = val.b_bool;
533 if( p_sys->i_vcodec )
535 msg_Dbg( p_stream, "codec video=%4.4s %dx%d scaling: %f %dkb/s",
536 (char *)&p_sys->i_vcodec, p_sys->i_width, p_sys->i_height,
537 p_sys->f_scale, p_sys->i_vbitrate / 1000 );
540 /* Subpictures transcoding parameters */
542 p_sys->psz_senc = NULL;
543 p_sys->p_spu_cfg = NULL;
546 var_Get( p_stream, SOUT_CFG_PREFIX "senc", &val );
547 if( val.psz_string && *val.psz_string )
550 psz_next = config_ChainCreate( &p_sys->psz_senc, &p_sys->p_spu_cfg,
554 free( val.psz_string );
556 var_Get( p_stream, SOUT_CFG_PREFIX "scodec", &val );
557 if( val.psz_string && *val.psz_string )
560 memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) );
561 p_sys->i_scodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
563 free( val.psz_string );
565 if( p_sys->i_scodec )
567 msg_Dbg( p_stream, "codec spu=%4.4s", (char *)&p_sys->i_scodec );
570 var_Get( p_stream, SOUT_CFG_PREFIX "soverlay", &val );
571 p_sys->b_soverlay = val.b_bool;
573 var_Get( p_stream, SOUT_CFG_PREFIX "sfilter", &val );
574 if( val.psz_string && *val.psz_string )
576 p_sys->p_spu = spu_Create( p_stream );
577 var_Create( p_sys->p_spu, "sub-filter", VLC_VAR_STRING );
578 var_Set( p_sys->p_spu, "sub-filter", val );
579 spu_Init( p_sys->p_spu );
581 free( val.psz_string );
583 /* OSD menu transcoding parameters */
584 p_sys->psz_osdenc = NULL;
585 p_sys->p_osd_cfg = NULL;
586 p_sys->i_osdcodec = 0;
587 p_sys->b_osd = false;
589 var_Get( p_stream, SOUT_CFG_PREFIX "osd", &val );
595 psz_next = config_ChainCreate( &p_sys->psz_osdenc,
596 &p_sys->p_osd_cfg, strdup( "dvbsub") );
599 p_sys->i_osdcodec = VLC_FOURCC('Y','U','V','P' );
601 msg_Dbg( p_stream, "codec osd=%4.4s", (char *)&p_sys->i_osdcodec );
605 osd_val.psz_string = strdup("osdmenu");
606 p_sys->p_spu = spu_Create( p_stream );
607 var_Create( p_sys->p_spu, "sub-filter", VLC_VAR_STRING );
608 var_Set( p_sys->p_spu, "sub-filter", osd_val );
609 spu_Init( p_sys->p_spu );
610 free( osd_val.psz_string );
614 osd_val.psz_string = strdup("osdmenu");
615 var_Set( p_sys->p_spu, "sub-filter", osd_val );
616 free( osd_val.psz_string );
621 var_Get( p_stream, SOUT_CFG_PREFIX "audio-sync", &val );
622 p_sys->b_master_sync = val.b_bool;
623 if( p_sys->f_fps > 0 ) p_sys->b_master_sync = true;
625 p_stream->pf_add = Add;
626 p_stream->pf_del = Del;
627 p_stream->pf_send = Send;
628 p_stream->p_sys = p_sys;
633 /*****************************************************************************
635 *****************************************************************************/
636 static void Close( vlc_object_t * p_this )
638 sout_stream_t *p_stream = (sout_stream_t*)p_this;
639 sout_stream_sys_t *p_sys = p_stream->p_sys;
641 sout_StreamDelete( p_sys->p_out );
643 free( p_sys->psz_af2 );
645 while( p_sys->p_audio_cfg != NULL )
647 config_chain_t *p_next = p_sys->p_audio_cfg->p_next;
649 free( p_sys->p_audio_cfg->psz_name );
650 free( p_sys->p_audio_cfg->psz_value );
651 free( p_sys->p_audio_cfg );
653 p_sys->p_audio_cfg = p_next;
655 free( p_sys->psz_aenc );
657 free( p_sys->psz_vf2 );
659 while( p_sys->p_video_cfg != NULL )
661 config_chain_t *p_next = p_sys->p_video_cfg->p_next;
663 free( p_sys->p_video_cfg->psz_name );
664 free( p_sys->p_video_cfg->psz_value );
665 free( p_sys->p_video_cfg );
667 p_sys->p_video_cfg = p_next;
669 free( p_sys->psz_venc );
671 while( p_sys->p_deinterlace_cfg != NULL )
673 config_chain_t *p_next = p_sys->p_deinterlace_cfg->p_next;
675 free( p_sys->p_deinterlace_cfg->psz_name );
676 free( p_sys->p_deinterlace_cfg->psz_value );
677 free( p_sys->p_deinterlace_cfg );
679 p_sys->p_deinterlace_cfg = p_next;
681 free( p_sys->psz_deinterlace );
683 while( p_sys->p_spu_cfg != NULL )
685 config_chain_t *p_next = p_sys->p_spu_cfg->p_next;
687 free( p_sys->p_spu_cfg->psz_name );
688 free( p_sys->p_spu_cfg->psz_value );
689 free( p_sys->p_spu_cfg );
691 p_sys->p_spu_cfg = p_next;
693 free( p_sys->psz_senc );
695 if( p_sys->p_spu ) spu_Destroy( p_sys->p_spu );
697 while( p_sys->p_osd_cfg != NULL )
699 config_chain_t *p_next = p_sys->p_osd_cfg->p_next;
701 free( p_sys->p_osd_cfg->psz_name );
702 free( p_sys->p_osd_cfg->psz_value );
703 free( p_sys->p_osd_cfg );
705 p_sys->p_osd_cfg = p_next;
707 free( p_sys->psz_osdenc );
709 vlc_object_release( p_sys );
712 struct sout_stream_id_t
714 vlc_fourcc_t b_transcode;
716 /* id of the out stream */
720 decoder_t *p_decoder;
723 filter_chain_t *p_f_chain;
724 /* User specified filters */
725 filter_chain_t *p_uf_chain;
728 encoder_t *p_encoder;
731 date_t interpolated_pts;
734 static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
736 sout_stream_sys_t *p_sys = p_stream->p_sys;
737 sout_stream_id_t *id;
739 id = malloc( sizeof( sout_stream_id_t ) );
742 msg_Err( p_stream, "out of memory" );
745 memset( id, 0, sizeof(sout_stream_id_t) );
748 id->p_decoder = NULL;
749 id->p_encoder = NULL;
751 /* Create decoder object */
752 id->p_decoder = vlc_object_create( p_stream, VLC_OBJECT_DECODER );
755 msg_Err( p_stream, "out of memory" );
758 vlc_object_attach( id->p_decoder, p_stream );
759 id->p_decoder->p_module = NULL;
760 id->p_decoder->fmt_in = *p_fmt;
761 id->p_decoder->b_pace_control = true;
763 /* Create encoder object */
764 id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
767 msg_Err( p_stream, "out of memory" );
770 vlc_object_attach( id->p_encoder, p_stream );
771 id->p_encoder->p_module = NULL;
773 /* Create destination format */
774 es_format_Init( &id->p_encoder->fmt_out, p_fmt->i_cat, 0 );
775 id->p_encoder->fmt_out.i_id = p_fmt->i_id;
776 id->p_encoder->fmt_out.i_group = p_fmt->i_group;
777 if( p_fmt->psz_language )
778 id->p_encoder->fmt_out.psz_language = strdup( p_fmt->psz_language );
780 if( p_fmt->i_cat == AUDIO_ES && (p_sys->i_acodec || p_sys->psz_aenc) )
783 "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
784 (char*)&p_fmt->i_codec, (char*)&p_sys->i_acodec );
786 /* Complete destination format */
787 id->p_encoder->fmt_out.i_codec = p_sys->i_acodec;
788 id->p_encoder->fmt_out.audio.i_rate = p_sys->i_sample_rate > 0 ?
789 p_sys->i_sample_rate : p_fmt->audio.i_rate;
790 id->p_encoder->fmt_out.i_bitrate = p_sys->i_abitrate;
791 id->p_encoder->fmt_out.audio.i_bitspersample =
792 p_fmt->audio.i_bitspersample;
793 id->p_encoder->fmt_out.audio.i_channels = p_sys->i_channels > 0 ?
794 p_sys->i_channels : p_fmt->audio.i_channels;
795 /* Sanity check for audio channels */
796 id->p_encoder->fmt_out.audio.i_channels =
797 __MIN( id->p_encoder->fmt_out.audio.i_channels,
798 id->p_decoder->fmt_in.audio.i_channels );
799 id->p_encoder->fmt_out.audio.i_original_channels =
800 id->p_decoder->fmt_in.audio.i_physical_channels;
801 if( id->p_decoder->fmt_in.audio.i_channels ==
802 id->p_encoder->fmt_out.audio.i_channels )
804 id->p_encoder->fmt_out.audio.i_physical_channels =
805 id->p_decoder->fmt_in.audio.i_physical_channels;
809 id->p_encoder->fmt_out.audio.i_physical_channels =
810 pi_channels_maps[id->p_encoder->fmt_out.audio.i_channels];
813 /* Build decoder -> filter -> encoder chain */
814 if( transcode_audio_new( p_stream, id ) )
816 msg_Err( p_stream, "cannot create audio chain" );
820 /* Open output stream */
821 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_encoder->fmt_out );
822 id->b_transcode = true;
826 transcode_audio_close( id );
830 date_Init( &id->interpolated_pts, p_fmt->audio.i_rate, 1 );
832 else if( p_fmt->i_cat == VIDEO_ES &&
833 (p_sys->i_vcodec != 0 || p_sys->psz_venc) )
836 "creating video transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
837 (char*)&p_fmt->i_codec, (char*)&p_sys->i_vcodec );
839 /* Complete destination format */
840 id->p_encoder->fmt_out.i_codec = p_sys->i_vcodec;
841 id->p_encoder->fmt_out.video.i_width = p_sys->i_width & ~1;
842 id->p_encoder->fmt_out.video.i_height = p_sys->i_height & ~1;
843 id->p_encoder->fmt_out.i_bitrate = p_sys->i_vbitrate;
845 /* Build decoder -> filter -> encoder chain */
846 if( transcode_video_new( p_stream, id ) )
848 msg_Err( p_stream, "cannot create video chain" );
852 /* Stream will be added later on because we don't know
853 * all the characteristics of the decoded stream yet */
854 id->b_transcode = true;
856 if( p_sys->f_fps > 0 )
858 id->p_encoder->fmt_out.video.i_frame_rate =
859 (p_sys->f_fps * 1000) + 0.5;
860 id->p_encoder->fmt_out.video.i_frame_rate_base =
864 else if( ( p_fmt->i_cat == SPU_ES ) &&
865 ( p_sys->i_scodec || p_sys->psz_senc ) )
867 msg_Dbg( p_stream, "creating subtitles transcoding from fcc=`%4.4s' "
868 "to fcc=`%4.4s'", (char*)&p_fmt->i_codec,
869 (char*)&p_sys->i_scodec );
871 /* Complete destination format */
872 id->p_encoder->fmt_out.i_codec = p_sys->i_scodec;
874 /* build decoder -> filter -> encoder */
875 if( transcode_spu_new( p_stream, id ) )
877 msg_Err( p_stream, "cannot create subtitles chain" );
881 /* open output stream */
882 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_encoder->fmt_out );
883 id->b_transcode = true;
887 transcode_spu_close( id );
891 else if( p_fmt->i_cat == SPU_ES && p_sys->b_soverlay )
893 msg_Dbg( p_stream, "subtitles (fcc=`%4.4s') overlaying",
894 (char*)&p_fmt->i_codec );
896 id->b_transcode = true;
898 /* Build decoder -> filter -> overlaying chain */
899 if( transcode_spu_new( p_stream, id ) )
901 msg_Err( p_stream, "cannot create subtitles chain" );
905 else if( !p_sys->b_osd && (p_sys->i_osdcodec != 0 || p_sys->psz_osdenc) )
907 msg_Dbg( p_stream, "creating osd transcoding from fcc=`%4.4s' "
908 "to fcc=`%4.4s'", (char*)&p_fmt->i_codec,
909 (char*)&p_sys->i_scodec );
911 id->b_transcode = true;
913 /* Create a fake OSD menu elementary stream */
914 if( transcode_osd_new( p_stream, id ) )
916 msg_Err( p_stream, "cannot create osd chain" );
923 msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
924 (char*)&p_fmt->i_codec );
925 id->id = p_sys->p_out->pf_add( p_sys->p_out, p_fmt );
926 id->b_transcode = false;
928 if( !id->id ) goto error;
936 vlc_object_detach( id->p_decoder );
937 vlc_object_release( id->p_decoder );
938 id->p_decoder = NULL;
943 vlc_object_detach( id->p_encoder );
944 es_format_Clean( &id->p_encoder->fmt_out );
945 vlc_object_release( id->p_encoder );
946 id->p_encoder = NULL;
953 static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
955 sout_stream_sys_t *p_sys = p_stream->p_sys;
957 if( id->b_transcode )
959 switch( id->p_decoder->fmt_in.i_cat )
962 transcode_audio_close( id );
965 transcode_video_close( p_stream, id );
969 transcode_osd_close( p_stream, id );
971 transcode_spu_close( id );
976 if( id->id ) p_sys->p_out->pf_del( p_sys->p_out, id->id );
980 vlc_object_detach( id->p_decoder );
981 vlc_object_release( id->p_decoder );
982 id->p_decoder = NULL;
987 vlc_object_detach( id->p_encoder );
988 es_format_Clean( &id->p_encoder->fmt_out );
989 vlc_object_release( id->p_encoder );
990 id->p_encoder = NULL;
997 static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
1000 sout_stream_sys_t *p_sys = p_stream->p_sys;
1001 block_t *p_out = NULL;
1003 if( !id->b_transcode && id->id )
1005 return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer );
1007 else if( !id->b_transcode )
1009 block_Release( p_buffer );
1010 return VLC_EGENERIC;
1013 switch( id->p_decoder->fmt_in.i_cat )
1016 transcode_audio_process( p_stream, id, p_buffer, &p_out );
1020 if( transcode_video_process( p_stream, id, p_buffer, &p_out )
1023 return VLC_EGENERIC;
1028 /* Transcode OSD menu pictures. */
1031 if( transcode_osd_process( p_stream, id, p_buffer, &p_out ) !=
1034 return VLC_EGENERIC;
1037 else if ( transcode_spu_process( p_stream, id, p_buffer, &p_out ) !=
1040 return VLC_EGENERIC;
1046 block_Release( p_buffer );
1050 if( p_out ) return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_out );
1054 /****************************************************************************
1056 ****************************************************************************/
1057 static inline void video_timer_start( encoder_t * p_encoder )
1059 stats_TimerStart( p_encoder, "encoding video frame",
1060 STATS_TIMER_VIDEO_FRAME_ENCODING );
1063 static inline void video_timer_stop( encoder_t * p_encoder )
1065 stats_TimerStop( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1068 static inline void video_timer_close( encoder_t * p_encoder )
1070 stats_TimerDump( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1071 stats_TimerClean( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1074 static inline void audio_timer_start( encoder_t * p_encoder )
1076 stats_TimerStart( p_encoder, "encoding audio frame",
1077 STATS_TIMER_AUDIO_FRAME_ENCODING );
1080 static inline void audio_timer_stop( encoder_t * p_encoder )
1082 stats_TimerStop( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1085 static inline void audio_timer_close( encoder_t * p_encoder )
1087 stats_TimerDump( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1088 stats_TimerClean( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1091 /****************************************************************************
1092 * decoder reencoder part
1093 ****************************************************************************/
1095 static int audio_BitsPerSample( vlc_fourcc_t i_format )
1099 case VLC_FOURCC('u','8',' ',' '):
1100 case VLC_FOURCC('s','8',' ',' '):
1103 case VLC_FOURCC('u','1','6','l'):
1104 case VLC_FOURCC('s','1','6','l'):
1105 case VLC_FOURCC('u','1','6','b'):
1106 case VLC_FOURCC('s','1','6','b'):
1109 case VLC_FOURCC('u','2','4','l'):
1110 case VLC_FOURCC('s','2','4','l'):
1111 case VLC_FOURCC('u','2','4','b'):
1112 case VLC_FOURCC('s','2','4','b'):
1115 case VLC_FOURCC('u','3','2','l'):
1116 case VLC_FOURCC('s','3','2','l'):
1117 case VLC_FOURCC('u','3','2','b'):
1118 case VLC_FOURCC('s','3','2','b'):
1119 case VLC_FOURCC('f','l','3','2'):
1120 case VLC_FOURCC('f','i','3','2'):
1123 case VLC_FOURCC('f','l','6','4'):
1130 static block_t *transcode_audio_alloc( filter_t *filter, int size )
1132 return block_New( filter, size );
1135 static int transcode_audio_filter_allocation_init( filter_t *p_filter,
1139 p_filter->pf_audio_buffer_new = transcode_audio_alloc;
1143 static int transcode_audio_new( sout_stream_t *p_stream,
1144 sout_stream_id_t *id )
1146 sout_stream_sys_t *p_sys = p_stream->p_sys;
1147 es_format_t fmt_last;
1153 /* Initialization of decoder structures */
1154 id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1155 id->p_decoder->fmt_out.i_extra = 0;
1156 id->p_decoder->fmt_out.p_extra = 0;
1157 id->p_decoder->pf_decode_audio = NULL;
1158 id->p_decoder->pf_aout_buffer_new = audio_new_buffer;
1159 id->p_decoder->pf_aout_buffer_del = audio_del_buffer;
1160 /* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */
1162 id->p_decoder->p_module =
1163 module_Need( id->p_decoder, "decoder", "$codec", 0 );
1164 if( !id->p_decoder->p_module )
1166 msg_Err( p_stream, "cannot find audio decoder" );
1167 return VLC_EGENERIC;
1169 id->p_decoder->fmt_out.audio.i_bitspersample =
1170 audio_BitsPerSample( id->p_decoder->fmt_out.i_codec );
1171 fmt_last = id->p_decoder->fmt_out;
1172 /* Fix AAC SBR changing number of channels and sampling rate */
1173 if( !(id->p_decoder->fmt_in.i_codec == VLC_FOURCC('m','p','4','a') &&
1174 fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate &&
1175 fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels) )
1176 fmt_last.audio.i_rate = id->p_decoder->fmt_in.audio.i_rate;
1182 /* Initialization of encoder format structures */
1183 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1184 id->p_decoder->fmt_out.i_codec );
1185 id->p_encoder->fmt_in.audio.i_format = id->p_decoder->fmt_out.i_codec;
1187 if( ( id->p_encoder->fmt_out.i_codec == VLC_FOURCC('s','a','m','r') ) ||
1188 ( id->p_encoder->fmt_out.i_codec == VLC_FOURCC('s','a','w','b') ) )
1189 id->p_encoder->fmt_in.audio.i_rate = id->p_encoder->fmt_out.audio.i_rate;
1191 id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;
1192 id->p_encoder->fmt_in.audio.i_physical_channels =
1193 id->p_encoder->fmt_out.audio.i_physical_channels;
1194 id->p_encoder->fmt_in.audio.i_original_channels =
1195 id->p_encoder->fmt_out.audio.i_original_channels;
1196 id->p_encoder->fmt_in.audio.i_channels =
1197 id->p_encoder->fmt_out.audio.i_channels;
1198 id->p_encoder->fmt_in.audio.i_bitspersample =
1199 audio_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1201 id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1202 id->p_encoder->p_module =
1203 module_Need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1204 if( !id->p_encoder->p_module )
1206 msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)",
1207 p_sys->psz_aenc ? p_sys->psz_aenc : "any",
1208 (char *)&p_sys->i_acodec );
1209 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1210 id->p_decoder->p_module = NULL;
1211 return VLC_EGENERIC;
1213 id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1214 id->p_encoder->fmt_in.audio.i_bitspersample =
1215 audio_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1217 /* Init filter chain */
1218 id->p_f_chain = filter_chain_New( p_stream, "audio filter2", false,
1219 transcode_audio_filter_allocation_init, NULL, NULL );
1220 filter_chain_Reset( id->p_uf_chain, &fmt_last, &id->p_encoder->fmt_in );
1222 /* Load conversion filters */
1223 if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels ||
1224 fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1226 /* We'll have to go through fl32 first */
1227 es_format_t fmt_out = id->p_encoder->fmt_in;
1228 fmt_out.i_codec = fmt_out.audio.i_format = VLC_FOURCC('f','l','3','2');
1229 filter_chain_AppendFilter( id->p_f_chain, NULL, NULL, &fmt_last, &fmt_out );
1234 /* FIXME FIXME FIXME WHAT DOES THIS CODE DO? LOOKS LIKE IT'S RANDOMLY TRYING
1235 TO CHAIN A BUNCH OF AUDIO FILTERS */
1236 for( i = 0; i < TRANSCODE_FILTERS; i++ )
1238 if( (fmt_last.audio.i_channels !=
1239 id->p_encoder->fmt_in.audio.i_channels) ||
1240 (fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate) ||
1241 (fmt_last.i_codec != id->p_encoder->fmt_in.i_codec) )
1243 id->pp_filter[id->i_filter] =
1244 transcode_audio_filter_new( p_stream, id, &fmt_last,
1245 &id->p_encoder->fmt_in, NULL );
1247 if( id->pp_filter[id->i_filter] )
1255 /* Final checks to see if conversions were successful */
1256 if( fmt_last.i_codec != id->p_encoder->fmt_in.i_codec )
1258 msg_Err( p_stream, "no audio filter found (%4.4s->%4.4s)",
1259 (char *)&fmt_last.i_codec,
1260 (char *)&id->p_encoder->fmt_in.i_codec );
1261 transcode_audio_close( id );
1262 return VLC_EGENERIC;
1265 /* Load user specified audio filters now */
1266 if( p_sys->psz_af2 )
1268 id->p_uf_chain = filter_chain_New( p_stream, "audio filter2", false,
1269 transcode_audio_filter_allocation_init, NULL, NULL );
1270 filter_chain_Reset( id->p_uf_chain, &fmt_last, &id->p_encoder->fmt_in );
1271 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_af2 );
1274 if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels )
1277 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1278 id->p_encoder->p_module = NULL;
1280 /* This might work, but only if the encoder is restarted */
1281 id->p_encoder->fmt_in.audio.i_channels = fmt_last.audio.i_channels;
1282 id->p_encoder->fmt_out.audio.i_channels = fmt_last.audio.i_channels;
1284 id->p_encoder->fmt_in.audio.i_physical_channels =
1285 id->p_encoder->fmt_in.audio.i_original_channels =
1286 fmt_last.audio.i_physical_channels;
1287 id->p_encoder->fmt_out.audio.i_physical_channels =
1288 id->p_encoder->fmt_out.audio.i_original_channels =
1289 fmt_last.audio.i_physical_channels;
1291 msg_Dbg( p_stream, "number of audio channels for mixing changed, "
1292 "trying to reopen the encoder for mixing %i to %i channels",
1293 fmt_last.audio.i_channels,
1294 id->p_encoder->fmt_in.audio.i_channels );
1296 /* reload encoder */
1297 id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1298 id->p_encoder->p_module =
1299 module_Need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1300 if( !id->p_encoder->p_module )
1302 msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)",
1303 p_sys->psz_aenc ? p_sys->psz_aenc : "any",
1304 (char *)&p_sys->i_acodec );
1305 transcode_audio_close( id );
1306 return VLC_EGENERIC;
1308 id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1309 id->p_encoder->fmt_in.audio.i_bitspersample =
1310 audio_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1312 msg_Err( p_stream, "no audio filter found for mixing from"
1313 " %i to %i channels", fmt_last.audio.i_channels,
1314 id->p_encoder->fmt_in.audio.i_channels );
1316 transcode_audio_close( id );
1317 return VLC_EGENERIC;
1321 if( fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1323 msg_Err( p_stream, "no audio filter found for resampling from"
1324 " %iHz to %iHz", fmt_last.audio.i_rate,
1325 id->p_encoder->fmt_in.audio.i_rate );
1327 /* FIXME : this might work, but only if the encoder is restarted */
1328 id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;
1329 id->p_encoder->fmt_out.audio.i_rate = fmt_last.audio.i_rate;
1331 transcode_audio_close( id );
1332 return VLC_EGENERIC;
1336 /* FIXME: Hack for mp3 transcoding support */
1337 if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC( 'm','p','3',' ' ) )
1338 id->p_encoder->fmt_out.i_codec = VLC_FOURCC( 'm','p','g','a' );
1343 static void transcode_audio_close( sout_stream_id_t *id )
1345 audio_timer_close( id->p_encoder );
1348 if( id->p_decoder->p_module )
1349 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1350 id->p_decoder->p_module = NULL;
1353 if( id->p_encoder->p_module )
1354 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1355 id->p_encoder->p_module = NULL;
1359 filter_chain_Delete( id->p_f_chain );
1360 if( id->p_uf_chain )
1361 filter_chain_Delete( id->p_uf_chain );
1364 static int transcode_audio_process( sout_stream_t *p_stream,
1365 sout_stream_id_t *id,
1366 block_t *in, block_t **out )
1368 sout_stream_sys_t *p_sys = p_stream->p_sys;
1369 aout_buffer_t *p_audio_buf;
1370 block_t *p_block, *p_audio_block;
1373 while( (p_audio_buf = id->p_decoder->pf_decode_audio( id->p_decoder,
1376 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_AUDIO, 1 );
1377 if( p_sys->b_master_sync )
1379 mtime_t i_dts = date_Get( &id->interpolated_pts ) + 1;
1380 if ( p_audio_buf->start_date - i_dts > MASTER_SYNC_MAX_DRIFT
1381 || p_audio_buf->start_date - i_dts < -MASTER_SYNC_MAX_DRIFT )
1383 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1384 date_Set( &id->interpolated_pts, p_audio_buf->start_date );
1385 i_dts = p_audio_buf->start_date + 1;
1387 p_sys->i_master_drift = p_audio_buf->start_date - i_dts;
1388 date_Increment( &id->interpolated_pts, p_audio_buf->i_nb_samples );
1389 p_audio_buf->start_date -= p_sys->i_master_drift;
1390 p_audio_buf->end_date -= p_sys->i_master_drift;
1393 p_audio_block = p_audio_buf->p_sys;
1394 p_audio_block->i_buffer = p_audio_buf->i_nb_bytes;
1395 p_audio_block->i_dts = p_audio_block->i_pts =
1396 p_audio_buf->start_date;
1397 p_audio_block->i_length = p_audio_buf->end_date -
1398 p_audio_buf->start_date;
1399 p_audio_block->i_samples = p_audio_buf->i_nb_samples;
1401 /* Run filter chain */
1402 p_audio_block = filter_chain_AudioFilter( id->p_f_chain, p_audio_block );
1403 if( id->p_uf_chain )
1404 p_audio_block = filter_chain_AudioFilter( id->p_uf_chain, p_audio_block );
1405 assert( p_audio_block );
1407 p_audio_buf->p_buffer = p_audio_block->p_buffer;
1408 p_audio_buf->i_nb_bytes = p_audio_block->i_buffer;
1409 p_audio_buf->i_nb_samples = p_audio_block->i_samples;
1410 p_audio_buf->start_date = p_audio_block->i_dts;
1411 p_audio_buf->end_date = p_audio_block->i_dts + p_audio_block->i_length;
1413 audio_timer_start( id->p_encoder );
1414 p_block = id->p_encoder->pf_encode_audio( id->p_encoder, p_audio_buf );
1415 audio_timer_stop( id->p_encoder );
1417 block_ChainAppend( out, p_block );
1418 block_Release( p_audio_block );
1419 free( p_audio_buf );
1425 static void audio_release_buffer( aout_buffer_t *p_buffer )
1427 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1431 static aout_buffer_t *audio_new_buffer( decoder_t *p_dec, int i_samples )
1433 aout_buffer_t *p_buffer;
1437 if( p_dec->fmt_out.audio.i_bitspersample )
1439 i_size = i_samples * p_dec->fmt_out.audio.i_bitspersample / 8 *
1440 p_dec->fmt_out.audio.i_channels;
1442 else if( p_dec->fmt_out.audio.i_bytes_per_frame &&
1443 p_dec->fmt_out.audio.i_frame_length )
1445 i_size = i_samples * p_dec->fmt_out.audio.i_bytes_per_frame /
1446 p_dec->fmt_out.audio.i_frame_length;
1450 i_size = i_samples * 4 * p_dec->fmt_out.audio.i_channels;
1453 p_buffer = malloc( sizeof(aout_buffer_t) );
1454 if( !p_buffer ) return NULL;
1455 p_buffer->b_discontinuity = false;
1456 p_buffer->pf_release = audio_release_buffer;
1457 p_buffer->p_sys = p_block = block_New( p_dec, i_size );
1459 p_buffer->p_buffer = p_block->p_buffer;
1460 p_buffer->i_size = p_buffer->i_nb_bytes = p_block->i_buffer;
1461 p_buffer->i_nb_samples = i_samples;
1462 p_block->i_samples = i_samples;
1467 static void audio_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
1470 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1478 static int transcode_video_filter_allocation_init( filter_t *p_filter,
1481 sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_data;
1484 p_filter->pf_vout_buffer_new = video_new_buffer_filter;
1485 p_filter->pf_vout_buffer_del = video_del_buffer_filter;
1487 p_filter->p_owner = malloc( sizeof(filter_owner_sys_t) );
1488 if( !p_filter->p_owner )
1489 return VLC_EGENERIC;
1491 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1492 p_filter->p_owner->pp_pics[i] = 0;
1493 p_filter->p_owner->p_sys = p_sys;
1498 static void transcode_video_filter_allocation_clear( filter_t *p_filter )
1502 /* Clean-up pictures ring buffer */
1503 for( j = 0; j < PICTURE_RING_SIZE; j++ )
1505 if( p_filter->p_owner->pp_pics[j] )
1506 video_del_buffer( VLC_OBJECT(p_filter),
1507 p_filter->p_owner->pp_pics[j] );
1509 free( p_filter->p_owner );
1512 static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
1514 sout_stream_sys_t *p_sys = p_stream->p_sys;
1518 * Initialization of decoder structures
1520 id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1521 id->p_decoder->fmt_out.i_extra = 0;
1522 id->p_decoder->fmt_out.p_extra = 0;
1523 id->p_decoder->pf_decode_video = NULL;
1524 id->p_decoder->pf_get_cc = NULL;
1525 id->p_decoder->pf_get_cc = 0;
1526 id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
1527 id->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder;
1528 id->p_decoder->pf_picture_link = video_link_picture_decoder;
1529 id->p_decoder->pf_picture_unlink = video_unlink_picture_decoder;
1530 id->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) );
1531 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1532 id->p_decoder->p_owner->pp_pics[i] = 0;
1533 id->p_decoder->p_owner->p_sys = p_sys;
1534 /* id->p_decoder->p_cfg = p_sys->p_video_cfg; */
1536 id->p_decoder->p_module =
1537 module_Need( id->p_decoder, "decoder", "$codec", 0 );
1539 if( !id->p_decoder->p_module )
1541 msg_Err( p_stream, "cannot find video decoder" );
1542 return VLC_EGENERIC;
1547 * Because some info about the decoded input will only be available
1548 * once the first frame is decoded, we actually only test the availability
1549 * of the encoder here.
1552 /* Initialization of encoder format structures */
1553 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1554 id->p_decoder->fmt_out.i_codec );
1555 id->p_encoder->fmt_in.video.i_chroma = id->p_decoder->fmt_out.i_codec;
1557 /* The dimensions will be set properly later on.
1558 * Just put sensible values so we can test an encoder is available. */
1559 id->p_encoder->fmt_in.video.i_width =
1560 id->p_encoder->fmt_out.video.i_width ?:
1561 id->p_decoder->fmt_in.video.i_width ?: 16;
1562 id->p_encoder->fmt_in.video.i_height =
1563 id->p_encoder->fmt_out.video.i_height ?:
1564 id->p_decoder->fmt_in.video.i_height ?: 16;
1565 id->p_encoder->fmt_in.video.i_frame_rate = ENC_FRAMERATE;
1566 id->p_encoder->fmt_in.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1568 id->p_encoder->i_threads = p_sys->i_threads;
1569 id->p_encoder->p_cfg = p_sys->p_video_cfg;
1571 id->p_encoder->p_module =
1572 module_Need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1573 if( !id->p_encoder->p_module )
1575 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1576 p_sys->psz_venc ? p_sys->psz_venc : "any",
1577 (char *)&p_sys->i_vcodec );
1578 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1579 id->p_decoder->p_module = 0;
1580 return VLC_EGENERIC;
1583 /* Close the encoder.
1584 * We'll open it only when we have the first frame. */
1585 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1586 if( id->p_encoder->fmt_out.p_extra )
1588 free( id->p_encoder->fmt_out.p_extra );
1589 id->p_encoder->fmt_out.p_extra = NULL;
1590 id->p_encoder->fmt_out.i_extra = 0;
1592 id->p_encoder->p_module = NULL;
1594 if( p_sys->i_threads >= 1 )
1596 int i_priority = p_sys->b_high_priority ? VLC_THREAD_PRIORITY_OUTPUT :
1597 VLC_THREAD_PRIORITY_VIDEO;
1598 p_sys->id_video = id;
1599 vlc_mutex_init( &p_sys->lock_out );
1600 vlc_cond_init( p_stream, &p_sys->cond );
1601 memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) );
1602 p_sys->i_first_pic = 0;
1603 p_sys->i_last_pic = 0;
1604 p_sys->p_buffers = NULL;
1605 p_sys->b_die = p_sys->b_error = 0;
1606 if( vlc_thread_create( p_sys, "encoder", EncoderThread, i_priority,
1609 msg_Err( p_stream, "cannot spawn encoder thread" );
1610 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1611 id->p_decoder->p_module = 0;
1612 return VLC_EGENERIC;
1619 static int transcode_video_encoder_open( sout_stream_t *p_stream,
1620 sout_stream_id_t *id )
1622 sout_stream_sys_t *p_sys = p_stream->p_sys;
1624 /* Calculate scaling
1625 * width/height of source */
1626 int i_src_width = id->p_decoder->fmt_out.video.i_width;
1627 int i_src_height = id->p_decoder->fmt_out.video.i_height;
1629 /* with/height scaling */
1630 float f_scale_width = 1;
1631 float f_scale_height = 1;
1633 /* width/height of output stream */
1638 float f_aspect = (float)id->p_decoder->fmt_out.video.i_aspect /
1641 msg_Dbg( p_stream, "decoder aspect is %i:%i",
1642 id->p_decoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1644 /* Change f_aspect from source frame to source pixel */
1645 f_aspect = f_aspect * i_src_height / i_src_width;
1646 msg_Dbg( p_stream, "source pixel aspect is %f:1", f_aspect );
1648 /* Calculate scaling factor for specified parameters */
1649 if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1650 id->p_encoder->fmt_out.video.i_height <= 0 && p_sys->f_scale )
1652 /* Global scaling. Make sure width will remain a factor of 16 */
1655 int i_new_width = i_src_width * p_sys->f_scale;
1657 if( i_new_width % 16 <= 7 && i_new_width >= 16 )
1658 i_new_width -= i_new_width % 16;
1660 i_new_width += 16 - i_new_width % 16;
1662 f_real_scale = (float)( i_new_width ) / (float) i_src_width;
1664 i_new_height = __MAX( 16, i_src_height * (float)f_real_scale );
1666 f_scale_width = f_real_scale;
1667 f_scale_height = (float) i_new_height / (float) i_src_height;
1669 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1670 id->p_encoder->fmt_out.video.i_height <= 0 )
1672 /* Only width specified */
1673 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1674 f_scale_height = f_scale_width;
1676 else if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1677 id->p_encoder->fmt_out.video.i_height > 0 )
1679 /* Only height specified */
1680 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1681 f_scale_width = f_scale_height;
1683 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1684 id->p_encoder->fmt_out.video.i_height > 0 )
1686 /* Width and height specified */
1687 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1688 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1691 /* check maxwidth and maxheight
1693 if( p_sys->i_maxwidth && f_scale_width > (float)p_sys->i_maxwidth /
1696 f_scale_width = (float)p_sys->i_maxwidth / i_src_width;
1699 if( p_sys->i_maxheight && f_scale_height > (float)p_sys->i_maxheight /
1702 f_scale_height = (float)p_sys->i_maxheight / i_src_height;
1706 /* Change aspect ratio from source pixel to scaled pixel */
1707 f_aspect = f_aspect * f_scale_height / f_scale_width;
1708 msg_Dbg( p_stream, "scaled pixel aspect is %f:1", f_aspect );
1710 /* f_scale_width and f_scale_height are now final */
1711 /* Calculate width, height from scaling
1712 * Make sure its multiple of 2
1714 i_dst_width = 2 * (int)(f_scale_width*i_src_width/2+0.5);
1715 i_dst_height = 2 * (int)(f_scale_height*i_src_height/2+0.5);
1717 /* Change aspect ratio from scaled pixel to output frame */
1718 f_aspect = f_aspect * i_dst_width / i_dst_height;
1720 /* Store calculated values */
1721 id->p_encoder->fmt_out.video.i_width = i_dst_width;
1722 id->p_encoder->fmt_out.video.i_height = i_dst_height;
1724 id->p_encoder->fmt_in.video.i_width = i_dst_width;
1725 id->p_encoder->fmt_in.video.i_height = i_dst_height;
1727 msg_Dbg( p_stream, "source %ix%i, destination %ix%i",
1728 i_src_width, i_src_height,
1729 i_dst_width, i_dst_height
1732 /* Handle frame rate conversion */
1733 if( !id->p_encoder->fmt_out.video.i_frame_rate ||
1734 !id->p_encoder->fmt_out.video.i_frame_rate_base )
1736 if( id->p_decoder->fmt_out.video.i_frame_rate &&
1737 id->p_decoder->fmt_out.video.i_frame_rate_base )
1739 id->p_encoder->fmt_out.video.i_frame_rate =
1740 id->p_decoder->fmt_out.video.i_frame_rate;
1741 id->p_encoder->fmt_out.video.i_frame_rate_base =
1742 id->p_decoder->fmt_out.video.i_frame_rate_base;
1746 /* Pick a sensible default value */
1747 id->p_encoder->fmt_out.video.i_frame_rate = ENC_FRAMERATE;
1748 id->p_encoder->fmt_out.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1752 id->p_encoder->fmt_in.video.i_frame_rate =
1753 id->p_encoder->fmt_out.video.i_frame_rate;
1754 id->p_encoder->fmt_in.video.i_frame_rate_base =
1755 id->p_encoder->fmt_out.video.i_frame_rate_base;
1757 date_Init( &id->interpolated_pts,
1758 id->p_encoder->fmt_out.video.i_frame_rate,
1759 id->p_encoder->fmt_out.video.i_frame_rate_base );
1761 /* Check whether a particular aspect ratio was requested */
1762 if( !id->p_encoder->fmt_out.video.i_aspect )
1764 id->p_encoder->fmt_out.video.i_aspect =
1765 (int)( f_aspect * VOUT_ASPECT_FACTOR + 0.5 );
1767 id->p_encoder->fmt_in.video.i_aspect =
1768 id->p_encoder->fmt_out.video.i_aspect;
1770 msg_Dbg( p_stream, "encoder aspect is %i:%i",
1771 id->p_encoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1773 id->p_encoder->p_module =
1774 module_Need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1775 if( !id->p_encoder->p_module )
1777 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1778 p_sys->psz_venc ? p_sys->psz_venc : "any",
1779 (char *)&p_sys->i_vcodec );
1780 return VLC_EGENERIC;
1783 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1785 /* Hack for mp2v/mp1v transcoding support */
1786 if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','1','v') ||
1787 id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','2','v') )
1789 id->p_encoder->fmt_out.i_codec = VLC_FOURCC('m','p','g','v');
1792 id->id = p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out,
1793 &id->p_encoder->fmt_out );
1796 msg_Err( p_stream, "cannot add this stream" );
1797 return VLC_EGENERIC;
1803 static void transcode_video_close( sout_stream_t *p_stream,
1804 sout_stream_id_t *id )
1808 if( p_stream->p_sys->i_threads >= 1 )
1810 vlc_mutex_lock( &p_stream->p_sys->lock_out );
1811 vlc_object_kill( p_stream->p_sys );
1812 vlc_cond_signal( &p_stream->p_sys->cond );
1813 vlc_mutex_unlock( &p_stream->p_sys->lock_out );
1814 vlc_thread_join( p_stream->p_sys );
1815 vlc_mutex_destroy( &p_stream->p_sys->lock_out );
1816 vlc_cond_destroy( &p_stream->p_sys->cond );
1819 video_timer_close( id->p_encoder );
1822 if( id->p_decoder->p_module )
1823 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1825 if( id->p_decoder->p_owner )
1827 /* Clean-up pictures ring buffer */
1828 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1830 if( id->p_decoder->p_owner->pp_pics[i] )
1831 video_del_buffer( VLC_OBJECT(id->p_decoder),
1832 id->p_decoder->p_owner->pp_pics[i] );
1834 free( id->p_decoder->p_owner );
1838 if( id->p_encoder->p_module )
1839 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1843 filter_chain_Delete( id->p_f_chain );
1844 if( id->p_uf_chain )
1845 filter_chain_Delete( id->p_uf_chain );
1848 static int transcode_video_process( sout_stream_t *p_stream,
1849 sout_stream_id_t *id,
1850 block_t *in, block_t **out )
1852 sout_stream_sys_t *p_sys = p_stream->p_sys;
1853 int i_duplicate = 1;
1854 picture_t *p_pic, *p_pic2 = NULL;
1857 while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
1859 subpicture_t *p_subpic = NULL;
1861 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_VIDEO, 1 );
1863 if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )
1865 mtime_t current_date = mdate();
1866 if( current_date + 50000 > p_pic->date )
1868 msg_Dbg( p_stream, "late picture skipped (%"PRId64")",
1869 current_date + 50000 - p_pic->date );
1870 p_pic->pf_release( p_pic );
1875 if( p_sys->b_master_sync )
1877 mtime_t i_video_drift;
1878 mtime_t i_master_drift = p_sys->i_master_drift;
1881 i_pts = date_Get( &id->interpolated_pts ) + 1;
1882 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1883 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
1885 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1886 date_Set( &id->interpolated_pts, p_pic->date );
1887 i_pts = p_pic->date + 1;
1889 i_video_drift = p_pic->date - i_pts;
1892 /* Set the pts of the frame being encoded */
1893 p_pic->date = i_pts;
1895 if( i_video_drift < (i_master_drift - 50000) )
1898 msg_Dbg( p_stream, "dropping frame (%i)",
1899 (int)(i_video_drift - i_master_drift) );
1901 p_pic->pf_release( p_pic );
1904 else if( i_video_drift > (i_master_drift + 50000) )
1907 msg_Dbg( p_stream, "adding frame (%i)",
1908 (int)(i_video_drift - i_master_drift) );
1914 if( !id->p_encoder->p_module )
1916 if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS )
1918 p_pic->pf_release( p_pic );
1919 transcode_video_close( p_stream, id );
1920 id->b_transcode = false;
1921 return VLC_EGENERIC;
1924 id->p_f_chain = filter_chain_New( p_stream, "video filter2",
1926 transcode_video_filter_allocation_init,
1927 transcode_video_filter_allocation_clear,
1931 if( p_stream->p_sys->b_deinterlace )
1933 filter_chain_AppendFilter( id->p_f_chain,
1934 p_sys->psz_deinterlace,
1935 p_sys->p_deinterlace_cfg,
1936 &id->p_decoder->fmt_out,
1937 &id->p_decoder->fmt_out );
1940 /* Take care of the scaling and chroma conversions */
1941 if( ( id->p_decoder->fmt_out.video.i_chroma !=
1942 id->p_encoder->fmt_in.video.i_chroma ) ||
1943 ( id->p_decoder->fmt_out.video.i_width !=
1944 id->p_encoder->fmt_in.video.i_width ) ||
1945 ( id->p_decoder->fmt_out.video.i_height !=
1946 id->p_encoder->fmt_in.video.i_height ) )
1948 filter_chain_AppendFilter( id->p_f_chain,
1950 &id->p_decoder->fmt_out,
1951 &id->p_encoder->fmt_in );
1954 if( p_sys->psz_vf2 )
1956 id->p_uf_chain = filter_chain_New( p_stream, "video filter2",
1958 transcode_video_filter_allocation_init,
1959 transcode_video_filter_allocation_clear,
1961 filter_chain_Reset( id->p_uf_chain, &id->p_decoder->fmt_out,
1962 &id->p_encoder->fmt_in );
1963 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_vf2 );
1967 /* Run filter chain */
1969 p_pic = filter_chain_VideoFilter( id->p_f_chain, p_pic );
1975 /* Check if we have a subpicture to overlay */
1978 p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date,
1979 false /* Fixme: check if stream is paused */ );
1980 /* TODO: get another pic */
1983 /* Overlay subpicture */
1986 int i_scale_width, i_scale_height;
1987 video_format_t *p_fmt;
1989 i_scale_width = id->p_encoder->fmt_in.video.i_width * 1000 /
1990 id->p_decoder->fmt_out.video.i_width;
1991 i_scale_height = id->p_encoder->fmt_in.video.i_height * 1000 /
1992 id->p_decoder->fmt_out.video.i_height;
1994 if( p_pic->i_refcount && !filter_chain_GetLength( id->p_f_chain ) )
1996 /* We can't modify the picture, we need to duplicate it */
1997 picture_t *p_tmp = video_new_buffer_decoder( id->p_decoder );
2000 vout_CopyPicture( p_stream, p_tmp, p_pic );
2001 p_pic->pf_release( p_pic );
2006 *p_fmt = filter_chain_GetFmtOut( id->p_f_chain )->video;
2008 /* FIXME (shouldn't have to be done here) */
2009 p_fmt->i_sar_num = p_fmt->i_aspect *
2010 p_fmt->i_height / p_fmt->i_width;
2011 p_fmt->i_sar_den = VOUT_ASPECT_FACTOR;
2013 spu_RenderSubpictures( p_sys->p_spu, p_fmt, p_pic, p_pic, p_subpic,
2014 i_scale_width, i_scale_height );
2017 /* Run user specified filter chain */
2018 if( id->p_uf_chain )
2019 p_pic = filter_chain_VideoFilter( id->p_uf_chain, p_pic );
2021 if( p_sys->i_threads == 0 )
2025 video_timer_start( id->p_encoder );
2026 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2027 video_timer_stop( id->p_encoder );
2029 block_ChainAppend( out, p_block );
2032 if( p_sys->b_master_sync )
2034 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
2035 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
2036 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
2038 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2039 date_Set( &id->interpolated_pts, p_pic->date );
2040 i_pts = p_pic->date + 1;
2042 date_Increment( &id->interpolated_pts, 1 );
2045 if( p_sys->b_master_sync && i_duplicate > 1 )
2047 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
2048 if( (p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT)
2049 || ((p_pic->date - i_pts) < -MASTER_SYNC_MAX_DRIFT) )
2051 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2052 date_Set( &id->interpolated_pts, p_pic->date );
2053 i_pts = p_pic->date + 1;
2055 date_Increment( &id->interpolated_pts, 1 );
2057 if( p_sys->i_threads >= 1 )
2059 /* We can't modify the picture, we need to duplicate it */
2060 p_pic2 = video_new_buffer_decoder( id->p_decoder );
2061 if( p_pic2 != NULL )
2063 vout_CopyPicture( p_stream, p_pic2, p_pic );
2064 p_pic2->date = i_pts;
2070 p_pic->date = i_pts;
2071 video_timer_start( id->p_encoder );
2072 p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);
2073 video_timer_stop( id->p_encoder );
2074 block_ChainAppend( out, p_block );
2078 if( p_sys->i_threads == 0 )
2080 p_pic->pf_release( p_pic );
2084 vlc_mutex_lock( &p_sys->lock_out );
2085 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
2086 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2087 *out = p_sys->p_buffers;
2088 p_sys->p_buffers = NULL;
2089 if( p_pic2 != NULL )
2091 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic2;
2092 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2094 vlc_cond_signal( &p_sys->cond );
2095 vlc_mutex_unlock( &p_sys->lock_out );
2102 static int EncoderThread( sout_stream_sys_t *p_sys )
2104 sout_stream_id_t *id = p_sys->id_video;
2107 while( !p_sys->b_die && !p_sys->b_error )
2111 vlc_mutex_lock( &p_sys->lock_out );
2112 while( p_sys->i_last_pic == p_sys->i_first_pic )
2114 vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );
2115 if( p_sys->b_die || p_sys->b_error ) break;
2117 if( p_sys->b_die || p_sys->b_error )
2119 vlc_mutex_unlock( &p_sys->lock_out );
2123 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2124 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2125 vlc_mutex_unlock( &p_sys->lock_out );
2127 video_timer_start( id->p_encoder );
2128 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2129 video_timer_stop( id->p_encoder );
2131 vlc_mutex_lock( &p_sys->lock_out );
2132 block_ChainAppend( &p_sys->p_buffers, p_block );
2134 vlc_mutex_unlock( &p_sys->lock_out );
2135 p_pic->pf_release( p_pic );
2138 while( p_sys->i_last_pic != p_sys->i_first_pic )
2140 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2141 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2142 p_pic->pf_release( p_pic );
2144 block_ChainRelease( p_sys->p_buffers );
2149 struct picture_sys_t
2151 vlc_object_t *p_owner;
2154 static void video_release_buffer( picture_t *p_pic )
2156 if( p_pic && !p_pic->i_refcount && p_pic->pf_release && p_pic->p_sys )
2158 video_del_buffer_decoder( (decoder_t *)p_pic->p_sys->p_owner, p_pic );
2160 else if( p_pic && p_pic->i_refcount > 0 ) p_pic->i_refcount--;
2163 static picture_t *video_new_buffer( vlc_object_t *p_this, picture_t **pp_ring,
2164 sout_stream_sys_t *p_sys )
2166 decoder_t *p_dec = (decoder_t *)p_this;
2170 /* Find an empty space in the picture ring buffer */
2171 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2173 if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2175 pp_ring[i]->i_status = RESERVED_PICTURE;
2179 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2181 if( pp_ring[i] == 0 ) break;
2184 if( i == PICTURE_RING_SIZE && p_sys->i_threads >= 1 )
2186 int i_first_pic = p_sys->i_first_pic;
2188 if( p_sys->i_first_pic != p_sys->i_last_pic )
2190 /* Encoder still has stuff to encode, wait to clear-up the list */
2191 while( p_sys->i_first_pic == i_first_pic )
2195 /* Find an empty space in the picture ring buffer */
2196 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2198 if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2200 pp_ring[i]->i_status = RESERVED_PICTURE;
2204 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2206 if( pp_ring[i] == 0 ) break;
2210 if( i == PICTURE_RING_SIZE )
2212 msg_Err( p_this, "decoder/filter is leaking pictures, "
2213 "resetting its ring buffer" );
2215 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2217 pp_ring[i]->pf_release( pp_ring[i] );
2223 p_pic = malloc( sizeof(picture_t) );
2224 if( !p_pic ) return NULL;
2225 p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
2226 vout_AllocatePicture( VLC_OBJECT(p_dec), p_pic,
2227 p_dec->fmt_out.video.i_chroma,
2228 p_dec->fmt_out.video.i_width,
2229 p_dec->fmt_out.video.i_height,
2230 p_dec->fmt_out.video.i_aspect );
2232 if( !p_pic->i_planes )
2238 p_pic->pf_release = video_release_buffer;
2239 p_pic->p_sys = malloc( sizeof(picture_sys_t) );
2246 p_pic->p_sys->p_owner = p_this;
2247 p_pic->i_status = RESERVED_PICTURE;
2253 static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
2255 return video_new_buffer( VLC_OBJECT(p_dec),
2256 p_dec->p_owner->pp_pics, p_dec->p_owner->p_sys );
2259 static picture_t *video_new_buffer_filter( filter_t *p_filter )
2261 return video_new_buffer( VLC_OBJECT(p_filter),
2262 p_filter->p_owner->pp_pics,
2263 p_filter->p_owner->p_sys );
2266 static void video_del_buffer( vlc_object_t *p_this, picture_t *p_pic )
2271 free( p_pic->p_data_orig );
2272 free( p_pic->p_sys );
2277 static void video_del_buffer_decoder( decoder_t *p_decoder, picture_t *p_pic )
2279 VLC_UNUSED(p_decoder);
2280 p_pic->i_refcount = 0;
2281 p_pic->i_status = DESTROYED_PICTURE;
2284 static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic )
2286 VLC_UNUSED(p_filter);
2287 p_pic->i_refcount = 0;
2288 p_pic->i_status = DESTROYED_PICTURE;
2291 static void video_link_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2294 p_pic->i_refcount++;
2297 static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2300 video_release_buffer( p_pic );
2306 static subpicture_t *spu_new_buffer( decoder_t * );
2307 static void spu_del_buffer( decoder_t *, subpicture_t * );
2309 static int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2311 sout_stream_sys_t *p_sys = p_stream->p_sys;
2317 /* Initialization of decoder structures */
2318 id->p_decoder->pf_decode_sub = NULL;
2319 id->p_decoder->pf_spu_buffer_new = spu_new_buffer;
2320 id->p_decoder->pf_spu_buffer_del = spu_del_buffer;
2321 id->p_decoder->p_owner = (decoder_owner_sys_t *)p_stream;
2322 /* id->p_decoder->p_cfg = p_sys->p_spu_cfg; */
2324 id->p_decoder->p_module =
2325 module_Need( id->p_decoder, "decoder", "$codec", 0 );
2327 if( !id->p_decoder->p_module )
2329 msg_Err( p_stream, "cannot find spu decoder" );
2330 return VLC_EGENERIC;
2333 if( !p_sys->b_soverlay )
2336 /* Initialization of encoder format structures */
2337 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2338 id->p_decoder->fmt_in.i_codec );
2340 id->p_encoder->p_cfg = p_sys->p_spu_cfg;
2342 id->p_encoder->p_module =
2343 module_Need( id->p_encoder, "encoder", p_sys->psz_senc, true );
2345 if( !id->p_encoder->p_module )
2347 module_Unneed( id->p_decoder, id->p_decoder->p_module );
2348 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_senc );
2349 return VLC_EGENERIC;
2355 p_sys->p_spu = spu_Create( p_stream );
2356 spu_Init( p_sys->p_spu );
2362 static void transcode_spu_close( sout_stream_id_t *id)
2365 if( id->p_decoder->p_module )
2366 module_Unneed( id->p_decoder, id->p_decoder->p_module );
2369 if( id->p_encoder->p_module )
2370 module_Unneed( id->p_encoder, id->p_encoder->p_module );
2373 static int transcode_spu_process( sout_stream_t *p_stream,
2374 sout_stream_id_t *id,
2375 block_t *in, block_t **out )
2377 sout_stream_sys_t *p_sys = p_stream->p_sys;
2378 subpicture_t *p_subpic;
2381 p_subpic = id->p_decoder->pf_decode_sub( id->p_decoder, &in );
2383 return VLC_EGENERIC;
2385 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_SUBTITLE, 1 );
2387 if( p_sys->b_master_sync && p_sys->i_master_drift )
2389 p_subpic->i_start -= p_sys->i_master_drift;
2390 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2393 if( p_sys->b_soverlay )
2395 spu_DisplaySubpicture( p_sys->p_spu, p_subpic );
2401 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2402 spu_del_buffer( id->p_decoder, p_subpic );
2405 block_ChainAppend( out, p_block );
2410 return VLC_EGENERIC;
2413 static subpicture_t *spu_new_buffer( decoder_t *p_dec )
2415 sout_stream_t *p_stream = (sout_stream_t *)p_dec->p_owner;
2416 return spu_CreateSubpicture( p_stream->p_sys->p_spu );
2419 static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
2421 sout_stream_t *p_stream = (sout_stream_t *)p_dec->p_owner;
2422 spu_DestroySubpicture( p_stream->p_sys->p_spu, p_subpic );
2428 static int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2430 sout_stream_sys_t *p_sys = p_stream->p_sys;
2432 id->p_decoder->fmt_in.i_cat = SPU_ES;
2433 id->p_encoder->fmt_out.psz_language = strdup( "osd" );
2435 if( p_sys->i_osdcodec != 0 || p_sys->psz_osdenc )
2437 msg_Dbg( p_stream, "creating osdmenu transcoding from fcc=`%4.4s' "
2438 "to fcc=`%4.4s'", (char*)&id->p_encoder->fmt_out.i_codec,
2439 (char*)&p_sys->i_osdcodec );
2441 /* Complete destination format */
2442 id->p_encoder->fmt_out.i_codec = p_sys->i_osdcodec;
2445 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2446 VLC_FOURCC('Y','U','V','A') );
2447 id->p_encoder->fmt_in.psz_language = strdup( "osd" );
2449 id->p_encoder->p_cfg = p_sys->p_osd_cfg;
2451 id->p_encoder->p_module =
2452 module_Need( id->p_encoder, "encoder", p_sys->psz_osdenc, true );
2454 if( !id->p_encoder->p_module )
2456 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_osdenc );
2460 /* open output stream */
2461 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_encoder->fmt_out );
2462 id->b_transcode = true;
2464 if( !id->id ) goto error;
2468 msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
2469 (char*)&id->p_decoder->fmt_out.i_codec );
2470 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_decoder->fmt_out );
2471 id->b_transcode = false;
2473 if( !id->id ) goto error;
2478 p_sys->p_spu = spu_Create( p_stream );
2479 spu_Init( p_sys->p_spu );
2485 msg_Err( p_stream, "starting osd encoding thread failed" );
2486 if( id->p_encoder->p_module )
2487 module_Unneed( id->p_encoder, id->p_encoder->p_module );
2488 p_sys->b_osd = false;
2489 return VLC_EGENERIC;
2492 static void transcode_osd_close( sout_stream_t *p_stream, sout_stream_id_t *id)
2494 sout_stream_sys_t *p_sys = p_stream->p_sys;
2499 if( id->p_encoder->p_module )
2500 module_Unneed( id->p_encoder, id->p_encoder->p_module );
2502 p_sys->b_osd = false;
2505 static int transcode_osd_process( sout_stream_t *p_stream,
2506 sout_stream_id_t *id,
2507 block_t *in, block_t **out )
2509 sout_stream_sys_t *p_sys = p_stream->p_sys;
2510 subpicture_t *p_subpic = NULL;
2512 /* Check if we have a subpicture to send */
2513 if( p_sys->p_spu && in->i_dts > 0)
2515 p_subpic = spu_SortSubpictures( p_sys->p_spu, in->i_dts, false );
2519 msg_Warn( p_stream, "spu channel not initialized, doing it now" );
2522 p_sys->p_spu = spu_Create( p_stream );
2523 spu_Init( p_sys->p_spu );
2529 block_t *p_block = NULL;
2531 if( p_sys->b_master_sync && p_sys->i_master_drift )
2533 p_subpic->i_start -= p_sys->i_master_drift;
2534 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2537 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2538 spu_DestroySubpicture( p_sys->p_spu, p_subpic );
2541 p_block->i_dts = p_block->i_pts = in->i_dts;
2542 block_ChainAppend( out, p_block );
2546 return VLC_EGENERIC;