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 *p_filter, int size )
1132 VLC_UNUSED( p_filter );
1133 return block_Alloc( size );
1136 static int transcode_audio_filter_allocation_init( filter_t *p_filter,
1140 p_filter->pf_audio_buffer_new = transcode_audio_alloc;
1144 static int transcode_audio_new( sout_stream_t *p_stream,
1145 sout_stream_id_t *id )
1147 sout_stream_sys_t *p_sys = p_stream->p_sys;
1148 es_format_t fmt_last;
1154 /* Initialization of decoder structures */
1155 id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1156 id->p_decoder->fmt_out.i_extra = 0;
1157 id->p_decoder->fmt_out.p_extra = 0;
1158 id->p_decoder->pf_decode_audio = NULL;
1159 id->p_decoder->pf_aout_buffer_new = audio_new_buffer;
1160 id->p_decoder->pf_aout_buffer_del = audio_del_buffer;
1161 /* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */
1163 id->p_decoder->p_module =
1164 module_Need( id->p_decoder, "decoder", "$codec", 0 );
1165 if( !id->p_decoder->p_module )
1167 msg_Err( p_stream, "cannot find audio decoder" );
1168 return VLC_EGENERIC;
1170 id->p_decoder->fmt_out.audio.i_bitspersample =
1171 audio_BitsPerSample( id->p_decoder->fmt_out.i_codec );
1172 fmt_last = id->p_decoder->fmt_out;
1173 /* Fix AAC SBR changing number of channels and sampling rate */
1174 if( !(id->p_decoder->fmt_in.i_codec == VLC_FOURCC('m','p','4','a') &&
1175 fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate &&
1176 fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels) )
1177 fmt_last.audio.i_rate = id->p_decoder->fmt_in.audio.i_rate;
1183 /* Initialization of encoder format structures */
1184 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1185 id->p_decoder->fmt_out.i_codec );
1186 id->p_encoder->fmt_in.audio.i_format = id->p_decoder->fmt_out.i_codec;
1188 if( ( id->p_encoder->fmt_out.i_codec == VLC_FOURCC('s','a','m','r') ) ||
1189 ( id->p_encoder->fmt_out.i_codec == VLC_FOURCC('s','a','w','b') ) )
1190 id->p_encoder->fmt_in.audio.i_rate = id->p_encoder->fmt_out.audio.i_rate;
1192 id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;
1193 id->p_encoder->fmt_in.audio.i_physical_channels =
1194 id->p_encoder->fmt_out.audio.i_physical_channels;
1195 id->p_encoder->fmt_in.audio.i_original_channels =
1196 id->p_encoder->fmt_out.audio.i_original_channels;
1197 id->p_encoder->fmt_in.audio.i_channels =
1198 id->p_encoder->fmt_out.audio.i_channels;
1199 id->p_encoder->fmt_in.audio.i_bitspersample =
1200 audio_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1202 id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1203 id->p_encoder->p_module =
1204 module_Need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1205 if( !id->p_encoder->p_module )
1207 msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)",
1208 p_sys->psz_aenc ? p_sys->psz_aenc : "any",
1209 (char *)&p_sys->i_acodec );
1210 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1211 id->p_decoder->p_module = NULL;
1212 return VLC_EGENERIC;
1214 id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1215 id->p_encoder->fmt_in.audio.i_bitspersample =
1216 audio_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1218 /* Init filter chain */
1219 id->p_f_chain = filter_chain_New( p_stream, "audio filter2", true,
1220 transcode_audio_filter_allocation_init, NULL, NULL );
1221 filter_chain_Reset( id->p_f_chain, &fmt_last, &id->p_encoder->fmt_in );
1223 /* Load conversion filters */
1224 if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels ||
1225 fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1227 /* We'll have to go through fl32 first */
1228 es_format_t fmt_out = id->p_encoder->fmt_in;
1229 fmt_out.i_codec = fmt_out.audio.i_format = VLC_FOURCC('f','l','3','2');
1230 filter_chain_AppendFilter( id->p_f_chain, NULL, NULL, &fmt_last, &fmt_out );
1234 /* FIXME: same comment as in "#if 0"ed code */
1236 for( i = 0; i < 4; 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 filter_chain_AppendFilter( id->p_f_chain, NULL, NULL, &fmt_last, &id->p_encoder->fmt_in );
1244 fmt_last = *filter_chain_GetFmtOut( id->p_f_chain );
1249 /* FIXME FIXME FIXME WHAT DOES THIS CODE DO? LOOKS LIKE IT'S RANDOMLY TRYING
1250 TO CHAIN A BUNCH OF AUDIO FILTERS */
1251 for( i = 0; i < TRANSCODE_FILTERS; i++ )
1253 if( (fmt_last.audio.i_channels !=
1254 id->p_encoder->fmt_in.audio.i_channels) ||
1255 (fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate) ||
1256 (fmt_last.i_codec != id->p_encoder->fmt_in.i_codec) )
1258 id->pp_filter[id->i_filter] =
1259 transcode_audio_filter_new( p_stream, id, &fmt_last,
1260 &id->p_encoder->fmt_in, NULL );
1262 if( id->pp_filter[id->i_filter] )
1270 /* Final checks to see if conversions were successful */
1271 if( fmt_last.i_codec != id->p_encoder->fmt_in.i_codec )
1273 msg_Err( p_stream, "no audio filter found (%4.4s->%4.4s)",
1274 (char *)&fmt_last.i_codec,
1275 (char *)&id->p_encoder->fmt_in.i_codec );
1276 transcode_audio_close( id );
1277 return VLC_EGENERIC;
1280 /* Load user specified audio filters now */
1281 if( p_sys->psz_af2 )
1283 id->p_uf_chain = filter_chain_New( p_stream, "audio filter2", false,
1284 transcode_audio_filter_allocation_init, NULL, NULL );
1285 filter_chain_Reset( id->p_uf_chain, &fmt_last, &id->p_encoder->fmt_in );
1286 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_af2 );
1289 if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels )
1292 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1293 id->p_encoder->p_module = NULL;
1295 /* This might work, but only if the encoder is restarted */
1296 id->p_encoder->fmt_in.audio.i_channels = fmt_last.audio.i_channels;
1297 id->p_encoder->fmt_out.audio.i_channels = fmt_last.audio.i_channels;
1299 id->p_encoder->fmt_in.audio.i_physical_channels =
1300 id->p_encoder->fmt_in.audio.i_original_channels =
1301 fmt_last.audio.i_physical_channels;
1302 id->p_encoder->fmt_out.audio.i_physical_channels =
1303 id->p_encoder->fmt_out.audio.i_original_channels =
1304 fmt_last.audio.i_physical_channels;
1306 msg_Dbg( p_stream, "number of audio channels for mixing changed, "
1307 "trying to reopen the encoder for mixing %i to %i channels",
1308 fmt_last.audio.i_channels,
1309 id->p_encoder->fmt_in.audio.i_channels );
1311 /* reload encoder */
1312 id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1313 id->p_encoder->p_module =
1314 module_Need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1315 if( !id->p_encoder->p_module )
1317 msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)",
1318 p_sys->psz_aenc ? p_sys->psz_aenc : "any",
1319 (char *)&p_sys->i_acodec );
1320 transcode_audio_close( id );
1321 return VLC_EGENERIC;
1323 id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1324 id->p_encoder->fmt_in.audio.i_bitspersample =
1325 audio_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1327 msg_Err( p_stream, "no audio filter found for mixing from"
1328 " %i to %i channels", fmt_last.audio.i_channels,
1329 id->p_encoder->fmt_in.audio.i_channels );
1331 transcode_audio_close( id );
1332 return VLC_EGENERIC;
1336 if( fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1338 msg_Err( p_stream, "no audio filter found for resampling from"
1339 " %iHz to %iHz", fmt_last.audio.i_rate,
1340 id->p_encoder->fmt_in.audio.i_rate );
1342 /* FIXME : this might work, but only if the encoder is restarted */
1343 id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;
1344 id->p_encoder->fmt_out.audio.i_rate = fmt_last.audio.i_rate;
1346 transcode_audio_close( id );
1347 return VLC_EGENERIC;
1351 /* FIXME: Hack for mp3 transcoding support */
1352 if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC( 'm','p','3',' ' ) )
1353 id->p_encoder->fmt_out.i_codec = VLC_FOURCC( 'm','p','g','a' );
1358 static void transcode_audio_close( sout_stream_id_t *id )
1360 audio_timer_close( id->p_encoder );
1363 if( id->p_decoder->p_module )
1364 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1365 id->p_decoder->p_module = NULL;
1368 if( id->p_encoder->p_module )
1369 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1370 id->p_encoder->p_module = NULL;
1374 filter_chain_Delete( id->p_f_chain );
1375 if( id->p_uf_chain )
1376 filter_chain_Delete( id->p_uf_chain );
1379 static int transcode_audio_process( sout_stream_t *p_stream,
1380 sout_stream_id_t *id,
1381 block_t *in, block_t **out )
1383 sout_stream_sys_t *p_sys = p_stream->p_sys;
1384 aout_buffer_t *p_audio_buf;
1385 block_t *p_block, *p_audio_block;
1388 while( (p_audio_buf = id->p_decoder->pf_decode_audio( id->p_decoder,
1391 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_AUDIO, 1 );
1392 if( p_sys->b_master_sync )
1394 mtime_t i_dts = date_Get( &id->interpolated_pts ) + 1;
1395 if ( p_audio_buf->start_date - i_dts > MASTER_SYNC_MAX_DRIFT
1396 || p_audio_buf->start_date - i_dts < -MASTER_SYNC_MAX_DRIFT )
1398 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1399 date_Set( &id->interpolated_pts, p_audio_buf->start_date );
1400 i_dts = p_audio_buf->start_date + 1;
1402 p_sys->i_master_drift = p_audio_buf->start_date - i_dts;
1403 date_Increment( &id->interpolated_pts, p_audio_buf->i_nb_samples );
1404 p_audio_buf->start_date -= p_sys->i_master_drift;
1405 p_audio_buf->end_date -= p_sys->i_master_drift;
1408 p_audio_block = p_audio_buf->p_sys;
1409 p_audio_block->i_buffer = p_audio_buf->i_nb_bytes;
1410 p_audio_block->i_dts = p_audio_block->i_pts =
1411 p_audio_buf->start_date;
1412 p_audio_block->i_length = p_audio_buf->end_date -
1413 p_audio_buf->start_date;
1414 p_audio_block->i_samples = p_audio_buf->i_nb_samples;
1416 /* Run filter chain */
1417 p_audio_block = filter_chain_AudioFilter( id->p_f_chain, p_audio_block );
1418 if( id->p_uf_chain )
1419 p_audio_block = filter_chain_AudioFilter( id->p_uf_chain, p_audio_block );
1420 assert( p_audio_block );
1422 p_audio_buf->p_buffer = p_audio_block->p_buffer;
1423 p_audio_buf->i_nb_bytes = p_audio_block->i_buffer;
1424 p_audio_buf->i_nb_samples = p_audio_block->i_samples;
1425 p_audio_buf->start_date = p_audio_block->i_dts;
1426 p_audio_buf->end_date = p_audio_block->i_dts + p_audio_block->i_length;
1428 audio_timer_start( id->p_encoder );
1429 p_block = id->p_encoder->pf_encode_audio( id->p_encoder, p_audio_buf );
1430 audio_timer_stop( id->p_encoder );
1432 block_ChainAppend( out, p_block );
1433 block_Release( p_audio_block );
1434 free( p_audio_buf );
1440 static void audio_release_buffer( aout_buffer_t *p_buffer )
1442 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1446 static aout_buffer_t *audio_new_buffer( decoder_t *p_dec, int i_samples )
1448 aout_buffer_t *p_buffer;
1452 if( p_dec->fmt_out.audio.i_bitspersample )
1454 i_size = i_samples * p_dec->fmt_out.audio.i_bitspersample / 8 *
1455 p_dec->fmt_out.audio.i_channels;
1457 else if( p_dec->fmt_out.audio.i_bytes_per_frame &&
1458 p_dec->fmt_out.audio.i_frame_length )
1460 i_size = i_samples * p_dec->fmt_out.audio.i_bytes_per_frame /
1461 p_dec->fmt_out.audio.i_frame_length;
1465 i_size = i_samples * 4 * p_dec->fmt_out.audio.i_channels;
1468 p_buffer = malloc( sizeof(aout_buffer_t) );
1469 if( !p_buffer ) return NULL;
1470 p_buffer->b_discontinuity = false;
1471 p_buffer->pf_release = audio_release_buffer;
1472 p_buffer->p_sys = p_block = block_New( p_dec, i_size );
1474 p_buffer->p_buffer = p_block->p_buffer;
1475 p_buffer->i_size = p_buffer->i_nb_bytes = p_block->i_buffer;
1476 p_buffer->i_nb_samples = i_samples;
1477 p_block->i_samples = i_samples;
1482 static void audio_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
1485 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1493 static int transcode_video_filter_allocation_init( filter_t *p_filter,
1496 sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_data;
1499 p_filter->pf_vout_buffer_new = video_new_buffer_filter;
1500 p_filter->pf_vout_buffer_del = video_del_buffer_filter;
1502 p_filter->p_owner = malloc( sizeof(filter_owner_sys_t) );
1503 if( !p_filter->p_owner )
1504 return VLC_EGENERIC;
1506 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1507 p_filter->p_owner->pp_pics[i] = 0;
1508 p_filter->p_owner->p_sys = p_sys;
1513 static void transcode_video_filter_allocation_clear( filter_t *p_filter )
1517 /* Clean-up pictures ring buffer */
1518 for( j = 0; j < PICTURE_RING_SIZE; j++ )
1520 if( p_filter->p_owner->pp_pics[j] )
1521 video_del_buffer( VLC_OBJECT(p_filter),
1522 p_filter->p_owner->pp_pics[j] );
1524 free( p_filter->p_owner );
1527 static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
1529 sout_stream_sys_t *p_sys = p_stream->p_sys;
1533 * Initialization of decoder structures
1535 id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1536 id->p_decoder->fmt_out.i_extra = 0;
1537 id->p_decoder->fmt_out.p_extra = 0;
1538 id->p_decoder->pf_decode_video = NULL;
1539 id->p_decoder->pf_get_cc = NULL;
1540 id->p_decoder->pf_get_cc = 0;
1541 id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
1542 id->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder;
1543 id->p_decoder->pf_picture_link = video_link_picture_decoder;
1544 id->p_decoder->pf_picture_unlink = video_unlink_picture_decoder;
1545 id->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) );
1546 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1547 id->p_decoder->p_owner->pp_pics[i] = 0;
1548 id->p_decoder->p_owner->p_sys = p_sys;
1549 /* id->p_decoder->p_cfg = p_sys->p_video_cfg; */
1551 id->p_decoder->p_module =
1552 module_Need( id->p_decoder, "decoder", "$codec", 0 );
1554 if( !id->p_decoder->p_module )
1556 msg_Err( p_stream, "cannot find video decoder" );
1557 return VLC_EGENERIC;
1562 * Because some info about the decoded input will only be available
1563 * once the first frame is decoded, we actually only test the availability
1564 * of the encoder here.
1567 /* Initialization of encoder format structures */
1568 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1569 id->p_decoder->fmt_out.i_codec );
1570 id->p_encoder->fmt_in.video.i_chroma = id->p_decoder->fmt_out.i_codec;
1572 /* The dimensions will be set properly later on.
1573 * Just put sensible values so we can test an encoder is available. */
1574 id->p_encoder->fmt_in.video.i_width =
1575 id->p_encoder->fmt_out.video.i_width ?:
1576 id->p_decoder->fmt_in.video.i_width ?: 16;
1577 id->p_encoder->fmt_in.video.i_height =
1578 id->p_encoder->fmt_out.video.i_height ?:
1579 id->p_decoder->fmt_in.video.i_height ?: 16;
1580 id->p_encoder->fmt_in.video.i_frame_rate = ENC_FRAMERATE;
1581 id->p_encoder->fmt_in.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1583 id->p_encoder->i_threads = p_sys->i_threads;
1584 id->p_encoder->p_cfg = p_sys->p_video_cfg;
1586 id->p_encoder->p_module =
1587 module_Need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1588 if( !id->p_encoder->p_module )
1590 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1591 p_sys->psz_venc ? p_sys->psz_venc : "any",
1592 (char *)&p_sys->i_vcodec );
1593 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1594 id->p_decoder->p_module = 0;
1595 return VLC_EGENERIC;
1598 /* Close the encoder.
1599 * We'll open it only when we have the first frame. */
1600 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1601 if( id->p_encoder->fmt_out.p_extra )
1603 free( id->p_encoder->fmt_out.p_extra );
1604 id->p_encoder->fmt_out.p_extra = NULL;
1605 id->p_encoder->fmt_out.i_extra = 0;
1607 id->p_encoder->p_module = NULL;
1609 if( p_sys->i_threads >= 1 )
1611 int i_priority = p_sys->b_high_priority ? VLC_THREAD_PRIORITY_OUTPUT :
1612 VLC_THREAD_PRIORITY_VIDEO;
1613 p_sys->id_video = id;
1614 vlc_mutex_init( &p_sys->lock_out );
1615 vlc_cond_init( p_stream, &p_sys->cond );
1616 memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) );
1617 p_sys->i_first_pic = 0;
1618 p_sys->i_last_pic = 0;
1619 p_sys->p_buffers = NULL;
1620 p_sys->b_die = p_sys->b_error = 0;
1621 if( vlc_thread_create( p_sys, "encoder", EncoderThread, i_priority,
1624 msg_Err( p_stream, "cannot spawn encoder thread" );
1625 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1626 id->p_decoder->p_module = 0;
1627 return VLC_EGENERIC;
1634 static int transcode_video_encoder_open( sout_stream_t *p_stream,
1635 sout_stream_id_t *id )
1637 sout_stream_sys_t *p_sys = p_stream->p_sys;
1639 /* Calculate scaling
1640 * width/height of source */
1641 int i_src_width = id->p_decoder->fmt_out.video.i_width;
1642 int i_src_height = id->p_decoder->fmt_out.video.i_height;
1644 /* with/height scaling */
1645 float f_scale_width = 1;
1646 float f_scale_height = 1;
1648 /* width/height of output stream */
1653 float f_aspect = (float)id->p_decoder->fmt_out.video.i_aspect /
1656 msg_Dbg( p_stream, "decoder aspect is %i:%i",
1657 id->p_decoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1659 /* Change f_aspect from source frame to source pixel */
1660 f_aspect = f_aspect * i_src_height / i_src_width;
1661 msg_Dbg( p_stream, "source pixel aspect is %f:1", f_aspect );
1663 /* Calculate scaling factor for specified parameters */
1664 if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1665 id->p_encoder->fmt_out.video.i_height <= 0 && p_sys->f_scale )
1667 /* Global scaling. Make sure width will remain a factor of 16 */
1670 int i_new_width = i_src_width * p_sys->f_scale;
1672 if( i_new_width % 16 <= 7 && i_new_width >= 16 )
1673 i_new_width -= i_new_width % 16;
1675 i_new_width += 16 - i_new_width % 16;
1677 f_real_scale = (float)( i_new_width ) / (float) i_src_width;
1679 i_new_height = __MAX( 16, i_src_height * (float)f_real_scale );
1681 f_scale_width = f_real_scale;
1682 f_scale_height = (float) i_new_height / (float) i_src_height;
1684 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1685 id->p_encoder->fmt_out.video.i_height <= 0 )
1687 /* Only width specified */
1688 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1689 f_scale_height = f_scale_width;
1691 else if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1692 id->p_encoder->fmt_out.video.i_height > 0 )
1694 /* Only height specified */
1695 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1696 f_scale_width = f_scale_height;
1698 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1699 id->p_encoder->fmt_out.video.i_height > 0 )
1701 /* Width and height specified */
1702 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1703 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1706 /* check maxwidth and maxheight
1708 if( p_sys->i_maxwidth && f_scale_width > (float)p_sys->i_maxwidth /
1711 f_scale_width = (float)p_sys->i_maxwidth / i_src_width;
1714 if( p_sys->i_maxheight && f_scale_height > (float)p_sys->i_maxheight /
1717 f_scale_height = (float)p_sys->i_maxheight / i_src_height;
1721 /* Change aspect ratio from source pixel to scaled pixel */
1722 f_aspect = f_aspect * f_scale_height / f_scale_width;
1723 msg_Dbg( p_stream, "scaled pixel aspect is %f:1", f_aspect );
1725 /* f_scale_width and f_scale_height are now final */
1726 /* Calculate width, height from scaling
1727 * Make sure its multiple of 2
1729 i_dst_width = 2 * (int)(f_scale_width*i_src_width/2+0.5);
1730 i_dst_height = 2 * (int)(f_scale_height*i_src_height/2+0.5);
1732 /* Change aspect ratio from scaled pixel to output frame */
1733 f_aspect = f_aspect * i_dst_width / i_dst_height;
1735 /* Store calculated values */
1736 id->p_encoder->fmt_out.video.i_width = i_dst_width;
1737 id->p_encoder->fmt_out.video.i_height = i_dst_height;
1739 id->p_encoder->fmt_in.video.i_width = i_dst_width;
1740 id->p_encoder->fmt_in.video.i_height = i_dst_height;
1742 msg_Dbg( p_stream, "source %ix%i, destination %ix%i",
1743 i_src_width, i_src_height,
1744 i_dst_width, i_dst_height
1747 /* Handle frame rate conversion */
1748 if( !id->p_encoder->fmt_out.video.i_frame_rate ||
1749 !id->p_encoder->fmt_out.video.i_frame_rate_base )
1751 if( id->p_decoder->fmt_out.video.i_frame_rate &&
1752 id->p_decoder->fmt_out.video.i_frame_rate_base )
1754 id->p_encoder->fmt_out.video.i_frame_rate =
1755 id->p_decoder->fmt_out.video.i_frame_rate;
1756 id->p_encoder->fmt_out.video.i_frame_rate_base =
1757 id->p_decoder->fmt_out.video.i_frame_rate_base;
1761 /* Pick a sensible default value */
1762 id->p_encoder->fmt_out.video.i_frame_rate = ENC_FRAMERATE;
1763 id->p_encoder->fmt_out.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1767 id->p_encoder->fmt_in.video.i_frame_rate =
1768 id->p_encoder->fmt_out.video.i_frame_rate;
1769 id->p_encoder->fmt_in.video.i_frame_rate_base =
1770 id->p_encoder->fmt_out.video.i_frame_rate_base;
1772 date_Init( &id->interpolated_pts,
1773 id->p_encoder->fmt_out.video.i_frame_rate,
1774 id->p_encoder->fmt_out.video.i_frame_rate_base );
1776 /* Check whether a particular aspect ratio was requested */
1777 if( !id->p_encoder->fmt_out.video.i_aspect )
1779 id->p_encoder->fmt_out.video.i_aspect =
1780 (int)( f_aspect * VOUT_ASPECT_FACTOR + 0.5 );
1782 id->p_encoder->fmt_in.video.i_aspect =
1783 id->p_encoder->fmt_out.video.i_aspect;
1785 msg_Dbg( p_stream, "encoder aspect is %i:%i",
1786 id->p_encoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1788 id->p_encoder->p_module =
1789 module_Need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1790 if( !id->p_encoder->p_module )
1792 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1793 p_sys->psz_venc ? p_sys->psz_venc : "any",
1794 (char *)&p_sys->i_vcodec );
1795 return VLC_EGENERIC;
1798 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1800 /* Hack for mp2v/mp1v transcoding support */
1801 if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','1','v') ||
1802 id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','2','v') )
1804 id->p_encoder->fmt_out.i_codec = VLC_FOURCC('m','p','g','v');
1807 id->id = p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out,
1808 &id->p_encoder->fmt_out );
1811 msg_Err( p_stream, "cannot add this stream" );
1812 return VLC_EGENERIC;
1818 static void transcode_video_close( sout_stream_t *p_stream,
1819 sout_stream_id_t *id )
1823 if( p_stream->p_sys->i_threads >= 1 )
1825 vlc_mutex_lock( &p_stream->p_sys->lock_out );
1826 vlc_object_kill( p_stream->p_sys );
1827 vlc_cond_signal( &p_stream->p_sys->cond );
1828 vlc_mutex_unlock( &p_stream->p_sys->lock_out );
1829 vlc_thread_join( p_stream->p_sys );
1830 vlc_mutex_destroy( &p_stream->p_sys->lock_out );
1831 vlc_cond_destroy( &p_stream->p_sys->cond );
1834 video_timer_close( id->p_encoder );
1837 if( id->p_decoder->p_module )
1838 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1840 if( id->p_decoder->p_owner )
1842 /* Clean-up pictures ring buffer */
1843 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1845 if( id->p_decoder->p_owner->pp_pics[i] )
1846 video_del_buffer( VLC_OBJECT(id->p_decoder),
1847 id->p_decoder->p_owner->pp_pics[i] );
1849 free( id->p_decoder->p_owner );
1853 if( id->p_encoder->p_module )
1854 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1858 filter_chain_Delete( id->p_f_chain );
1859 if( id->p_uf_chain )
1860 filter_chain_Delete( id->p_uf_chain );
1863 static int transcode_video_process( sout_stream_t *p_stream,
1864 sout_stream_id_t *id,
1865 block_t *in, block_t **out )
1867 sout_stream_sys_t *p_sys = p_stream->p_sys;
1868 int i_duplicate = 1;
1869 picture_t *p_pic, *p_pic2 = NULL;
1872 while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
1874 subpicture_t *p_subpic = NULL;
1876 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_VIDEO, 1 );
1878 if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )
1880 mtime_t current_date = mdate();
1881 if( current_date + 50000 > p_pic->date )
1883 msg_Dbg( p_stream, "late picture skipped (%"PRId64")",
1884 current_date + 50000 - p_pic->date );
1885 p_pic->pf_release( p_pic );
1890 if( p_sys->b_master_sync )
1892 mtime_t i_video_drift;
1893 mtime_t i_master_drift = p_sys->i_master_drift;
1896 i_pts = date_Get( &id->interpolated_pts ) + 1;
1897 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1898 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
1900 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1901 date_Set( &id->interpolated_pts, p_pic->date );
1902 i_pts = p_pic->date + 1;
1904 i_video_drift = p_pic->date - i_pts;
1907 /* Set the pts of the frame being encoded */
1908 p_pic->date = i_pts;
1910 if( i_video_drift < (i_master_drift - 50000) )
1913 msg_Dbg( p_stream, "dropping frame (%i)",
1914 (int)(i_video_drift - i_master_drift) );
1916 p_pic->pf_release( p_pic );
1919 else if( i_video_drift > (i_master_drift + 50000) )
1922 msg_Dbg( p_stream, "adding frame (%i)",
1923 (int)(i_video_drift - i_master_drift) );
1929 if( !id->p_encoder->p_module )
1931 if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS )
1933 p_pic->pf_release( p_pic );
1934 transcode_video_close( p_stream, id );
1935 id->b_transcode = false;
1936 return VLC_EGENERIC;
1939 id->p_f_chain = filter_chain_New( p_stream, "video filter2",
1941 transcode_video_filter_allocation_init,
1942 transcode_video_filter_allocation_clear,
1946 if( p_stream->p_sys->b_deinterlace )
1948 filter_chain_AppendFilter( id->p_f_chain,
1949 p_sys->psz_deinterlace,
1950 p_sys->p_deinterlace_cfg,
1951 &id->p_decoder->fmt_out,
1952 &id->p_decoder->fmt_out );
1955 /* Take care of the scaling and chroma conversions */
1956 if( ( id->p_decoder->fmt_out.video.i_chroma !=
1957 id->p_encoder->fmt_in.video.i_chroma ) ||
1958 ( id->p_decoder->fmt_out.video.i_width !=
1959 id->p_encoder->fmt_in.video.i_width ) ||
1960 ( id->p_decoder->fmt_out.video.i_height !=
1961 id->p_encoder->fmt_in.video.i_height ) )
1963 filter_chain_AppendFilter( id->p_f_chain,
1965 &id->p_decoder->fmt_out,
1966 &id->p_encoder->fmt_in );
1969 if( p_sys->psz_vf2 )
1971 id->p_uf_chain = filter_chain_New( p_stream, "video filter2",
1973 transcode_video_filter_allocation_init,
1974 transcode_video_filter_allocation_clear,
1976 filter_chain_Reset( id->p_uf_chain, &id->p_decoder->fmt_out,
1977 &id->p_encoder->fmt_in );
1978 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_vf2 );
1982 /* Run filter chain */
1984 p_pic = filter_chain_VideoFilter( id->p_f_chain, p_pic );
1990 /* Check if we have a subpicture to overlay */
1993 p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date,
1994 false /* Fixme: check if stream is paused */ );
1995 /* TODO: get another pic */
1998 /* Overlay subpicture */
2001 int i_scale_width, i_scale_height;
2004 i_scale_width = id->p_encoder->fmt_in.video.i_width * 1000 /
2005 id->p_decoder->fmt_out.video.i_width;
2006 i_scale_height = id->p_encoder->fmt_in.video.i_height * 1000 /
2007 id->p_decoder->fmt_out.video.i_height;
2009 if( p_pic->i_refcount && !filter_chain_GetLength( id->p_f_chain ) )
2011 /* We can't modify the picture, we need to duplicate it */
2012 picture_t *p_tmp = video_new_buffer_decoder( id->p_decoder );
2015 vout_CopyPicture( p_stream, p_tmp, p_pic );
2016 p_pic->pf_release( p_pic );
2021 fmt = filter_chain_GetFmtOut( id->p_f_chain )->video;
2023 /* FIXME (shouldn't have to be done here) */
2024 fmt.i_sar_num = fmt.i_aspect * fmt.i_height / fmt.i_width;
2025 fmt.i_sar_den = VOUT_ASPECT_FACTOR;
2027 spu_RenderSubpictures( p_sys->p_spu, &fmt, p_pic, p_pic, p_subpic,
2028 i_scale_width, i_scale_height );
2031 /* Run user specified filter chain */
2032 if( id->p_uf_chain )
2033 p_pic = filter_chain_VideoFilter( id->p_uf_chain, p_pic );
2035 if( p_sys->i_threads == 0 )
2039 video_timer_start( id->p_encoder );
2040 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2041 video_timer_stop( id->p_encoder );
2043 block_ChainAppend( out, p_block );
2046 if( p_sys->b_master_sync )
2048 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
2049 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
2050 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
2052 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2053 date_Set( &id->interpolated_pts, p_pic->date );
2054 i_pts = p_pic->date + 1;
2056 date_Increment( &id->interpolated_pts, 1 );
2059 if( p_sys->b_master_sync && i_duplicate > 1 )
2061 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
2062 if( (p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT)
2063 || ((p_pic->date - i_pts) < -MASTER_SYNC_MAX_DRIFT) )
2065 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2066 date_Set( &id->interpolated_pts, p_pic->date );
2067 i_pts = p_pic->date + 1;
2069 date_Increment( &id->interpolated_pts, 1 );
2071 if( p_sys->i_threads >= 1 )
2073 /* We can't modify the picture, we need to duplicate it */
2074 p_pic2 = video_new_buffer_decoder( id->p_decoder );
2075 if( p_pic2 != NULL )
2077 vout_CopyPicture( p_stream, p_pic2, p_pic );
2078 p_pic2->date = i_pts;
2084 p_pic->date = i_pts;
2085 video_timer_start( id->p_encoder );
2086 p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);
2087 video_timer_stop( id->p_encoder );
2088 block_ChainAppend( out, p_block );
2092 if( p_sys->i_threads == 0 )
2094 p_pic->pf_release( p_pic );
2098 vlc_mutex_lock( &p_sys->lock_out );
2099 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
2100 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2101 *out = p_sys->p_buffers;
2102 p_sys->p_buffers = NULL;
2103 if( p_pic2 != NULL )
2105 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic2;
2106 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2108 vlc_cond_signal( &p_sys->cond );
2109 vlc_mutex_unlock( &p_sys->lock_out );
2116 static int EncoderThread( sout_stream_sys_t *p_sys )
2118 sout_stream_id_t *id = p_sys->id_video;
2121 while( !p_sys->b_die && !p_sys->b_error )
2125 vlc_mutex_lock( &p_sys->lock_out );
2126 while( p_sys->i_last_pic == p_sys->i_first_pic )
2128 vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );
2129 if( p_sys->b_die || p_sys->b_error ) break;
2131 if( p_sys->b_die || p_sys->b_error )
2133 vlc_mutex_unlock( &p_sys->lock_out );
2137 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2138 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2139 vlc_mutex_unlock( &p_sys->lock_out );
2141 video_timer_start( id->p_encoder );
2142 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2143 video_timer_stop( id->p_encoder );
2145 vlc_mutex_lock( &p_sys->lock_out );
2146 block_ChainAppend( &p_sys->p_buffers, p_block );
2148 vlc_mutex_unlock( &p_sys->lock_out );
2149 p_pic->pf_release( p_pic );
2152 while( p_sys->i_last_pic != p_sys->i_first_pic )
2154 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2155 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2156 p_pic->pf_release( p_pic );
2158 block_ChainRelease( p_sys->p_buffers );
2163 struct picture_sys_t
2165 vlc_object_t *p_owner;
2168 static void video_release_buffer( picture_t *p_pic )
2170 if( p_pic && !p_pic->i_refcount && p_pic->pf_release && p_pic->p_sys )
2172 video_del_buffer_decoder( (decoder_t *)p_pic->p_sys->p_owner, p_pic );
2174 else if( p_pic && p_pic->i_refcount > 0 ) p_pic->i_refcount--;
2177 static picture_t *video_new_buffer( vlc_object_t *p_this, picture_t **pp_ring,
2178 sout_stream_sys_t *p_sys )
2180 decoder_t *p_dec = (decoder_t *)p_this;
2184 /* Find an empty space in the picture ring buffer */
2185 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2187 if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2189 pp_ring[i]->i_status = RESERVED_PICTURE;
2193 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2195 if( pp_ring[i] == 0 ) break;
2198 if( i == PICTURE_RING_SIZE && p_sys->i_threads >= 1 )
2200 int i_first_pic = p_sys->i_first_pic;
2202 if( p_sys->i_first_pic != p_sys->i_last_pic )
2204 /* Encoder still has stuff to encode, wait to clear-up the list */
2205 while( p_sys->i_first_pic == i_first_pic )
2209 /* Find an empty space in the picture ring buffer */
2210 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2212 if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2214 pp_ring[i]->i_status = RESERVED_PICTURE;
2218 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2220 if( pp_ring[i] == 0 ) break;
2224 if( i == PICTURE_RING_SIZE )
2226 msg_Err( p_this, "decoder/filter is leaking pictures, "
2227 "resetting its ring buffer" );
2229 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2231 pp_ring[i]->pf_release( pp_ring[i] );
2237 p_pic = malloc( sizeof(picture_t) );
2238 if( !p_pic ) return NULL;
2239 p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
2240 vout_AllocatePicture( VLC_OBJECT(p_dec), p_pic,
2241 p_dec->fmt_out.video.i_chroma,
2242 p_dec->fmt_out.video.i_width,
2243 p_dec->fmt_out.video.i_height,
2244 p_dec->fmt_out.video.i_aspect );
2246 if( !p_pic->i_planes )
2252 p_pic->pf_release = video_release_buffer;
2253 p_pic->p_sys = malloc( sizeof(picture_sys_t) );
2260 p_pic->p_sys->p_owner = p_this;
2261 p_pic->i_status = RESERVED_PICTURE;
2267 static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
2269 return video_new_buffer( VLC_OBJECT(p_dec),
2270 p_dec->p_owner->pp_pics, p_dec->p_owner->p_sys );
2273 static picture_t *video_new_buffer_filter( filter_t *p_filter )
2275 return video_new_buffer( VLC_OBJECT(p_filter),
2276 p_filter->p_owner->pp_pics,
2277 p_filter->p_owner->p_sys );
2280 static void video_del_buffer( vlc_object_t *p_this, picture_t *p_pic )
2285 free( p_pic->p_data_orig );
2286 free( p_pic->p_sys );
2291 static void video_del_buffer_decoder( decoder_t *p_decoder, picture_t *p_pic )
2293 VLC_UNUSED(p_decoder);
2294 p_pic->i_refcount = 0;
2295 p_pic->i_status = DESTROYED_PICTURE;
2298 static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic )
2300 VLC_UNUSED(p_filter);
2301 p_pic->i_refcount = 0;
2302 p_pic->i_status = DESTROYED_PICTURE;
2305 static void video_link_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2308 p_pic->i_refcount++;
2311 static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2314 video_release_buffer( p_pic );
2320 static subpicture_t *spu_new_buffer( decoder_t * );
2321 static void spu_del_buffer( decoder_t *, subpicture_t * );
2323 static int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2325 sout_stream_sys_t *p_sys = p_stream->p_sys;
2331 /* Initialization of decoder structures */
2332 id->p_decoder->pf_decode_sub = NULL;
2333 id->p_decoder->pf_spu_buffer_new = spu_new_buffer;
2334 id->p_decoder->pf_spu_buffer_del = spu_del_buffer;
2335 id->p_decoder->p_owner = (decoder_owner_sys_t *)p_stream;
2336 /* id->p_decoder->p_cfg = p_sys->p_spu_cfg; */
2338 id->p_decoder->p_module =
2339 module_Need( id->p_decoder, "decoder", "$codec", 0 );
2341 if( !id->p_decoder->p_module )
2343 msg_Err( p_stream, "cannot find spu decoder" );
2344 return VLC_EGENERIC;
2347 if( !p_sys->b_soverlay )
2350 /* Initialization of encoder format structures */
2351 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2352 id->p_decoder->fmt_in.i_codec );
2354 id->p_encoder->p_cfg = p_sys->p_spu_cfg;
2356 id->p_encoder->p_module =
2357 module_Need( id->p_encoder, "encoder", p_sys->psz_senc, true );
2359 if( !id->p_encoder->p_module )
2361 module_Unneed( id->p_decoder, id->p_decoder->p_module );
2362 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_senc );
2363 return VLC_EGENERIC;
2369 p_sys->p_spu = spu_Create( p_stream );
2370 spu_Init( p_sys->p_spu );
2376 static void transcode_spu_close( sout_stream_id_t *id)
2379 if( id->p_decoder->p_module )
2380 module_Unneed( id->p_decoder, id->p_decoder->p_module );
2383 if( id->p_encoder->p_module )
2384 module_Unneed( id->p_encoder, id->p_encoder->p_module );
2387 static int transcode_spu_process( sout_stream_t *p_stream,
2388 sout_stream_id_t *id,
2389 block_t *in, block_t **out )
2391 sout_stream_sys_t *p_sys = p_stream->p_sys;
2392 subpicture_t *p_subpic;
2395 p_subpic = id->p_decoder->pf_decode_sub( id->p_decoder, &in );
2397 return VLC_EGENERIC;
2399 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_SUBTITLE, 1 );
2401 if( p_sys->b_master_sync && p_sys->i_master_drift )
2403 p_subpic->i_start -= p_sys->i_master_drift;
2404 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2407 if( p_sys->b_soverlay )
2409 spu_DisplaySubpicture( p_sys->p_spu, p_subpic );
2415 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2416 spu_del_buffer( id->p_decoder, p_subpic );
2419 block_ChainAppend( out, p_block );
2424 return VLC_EGENERIC;
2427 static subpicture_t *spu_new_buffer( decoder_t *p_dec )
2429 sout_stream_t *p_stream = (sout_stream_t *)p_dec->p_owner;
2430 return spu_CreateSubpicture( p_stream->p_sys->p_spu );
2433 static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
2435 sout_stream_t *p_stream = (sout_stream_t *)p_dec->p_owner;
2436 spu_DestroySubpicture( p_stream->p_sys->p_spu, p_subpic );
2442 static int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2444 sout_stream_sys_t *p_sys = p_stream->p_sys;
2446 id->p_decoder->fmt_in.i_cat = SPU_ES;
2447 id->p_encoder->fmt_out.psz_language = strdup( "osd" );
2449 if( p_sys->i_osdcodec != 0 || p_sys->psz_osdenc )
2451 msg_Dbg( p_stream, "creating osdmenu transcoding from fcc=`%4.4s' "
2452 "to fcc=`%4.4s'", (char*)&id->p_encoder->fmt_out.i_codec,
2453 (char*)&p_sys->i_osdcodec );
2455 /* Complete destination format */
2456 id->p_encoder->fmt_out.i_codec = p_sys->i_osdcodec;
2459 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2460 VLC_FOURCC('Y','U','V','A') );
2461 id->p_encoder->fmt_in.psz_language = strdup( "osd" );
2463 id->p_encoder->p_cfg = p_sys->p_osd_cfg;
2465 id->p_encoder->p_module =
2466 module_Need( id->p_encoder, "encoder", p_sys->psz_osdenc, true );
2468 if( !id->p_encoder->p_module )
2470 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_osdenc );
2474 /* open output stream */
2475 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_encoder->fmt_out );
2476 id->b_transcode = true;
2478 if( !id->id ) goto error;
2482 msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
2483 (char*)&id->p_decoder->fmt_out.i_codec );
2484 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_decoder->fmt_out );
2485 id->b_transcode = false;
2487 if( !id->id ) goto error;
2492 p_sys->p_spu = spu_Create( p_stream );
2493 spu_Init( p_sys->p_spu );
2499 msg_Err( p_stream, "starting osd encoding thread failed" );
2500 if( id->p_encoder->p_module )
2501 module_Unneed( id->p_encoder, id->p_encoder->p_module );
2502 p_sys->b_osd = false;
2503 return VLC_EGENERIC;
2506 static void transcode_osd_close( sout_stream_t *p_stream, sout_stream_id_t *id)
2508 sout_stream_sys_t *p_sys = p_stream->p_sys;
2513 if( id->p_encoder->p_module )
2514 module_Unneed( id->p_encoder, id->p_encoder->p_module );
2516 p_sys->b_osd = false;
2519 static int transcode_osd_process( sout_stream_t *p_stream,
2520 sout_stream_id_t *id,
2521 block_t *in, block_t **out )
2523 sout_stream_sys_t *p_sys = p_stream->p_sys;
2524 subpicture_t *p_subpic = NULL;
2526 /* Check if we have a subpicture to send */
2527 if( p_sys->p_spu && in->i_dts > 0)
2529 p_subpic = spu_SortSubpictures( p_sys->p_spu, in->i_dts, false );
2533 msg_Warn( p_stream, "spu channel not initialized, doing it now" );
2536 p_sys->p_spu = spu_Create( p_stream );
2537 spu_Init( p_sys->p_spu );
2543 block_t *p_block = NULL;
2545 if( p_sys->b_master_sync && p_sys->i_master_drift )
2547 p_subpic->i_start -= p_sys->i_master_drift;
2548 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2551 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2552 spu_DestroySubpicture( p_sys->p_spu, p_subpic );
2555 p_block->i_dts = p_block->i_pts = in->i_dts;
2556 block_ChainAppend( out, p_block );
2560 return VLC_EGENERIC;