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", true,
1219 transcode_audio_filter_allocation_init, NULL, NULL );
1220 filter_chain_Reset( id->p_f_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 );
1233 /* FIXME: same comment as in "#if 0"ed code */
1235 for( i = 0; i < 4; i++ )
1237 if( (fmt_last.audio.i_channels !=
1238 id->p_encoder->fmt_in.audio.i_channels) ||
1239 (fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate) ||
1240 (fmt_last.i_codec != id->p_encoder->fmt_in.i_codec) )
1242 filter_chain_AppendFilter( id->p_f_chain, NULL, NULL, &fmt_last, &id->p_encoder->fmt_in );
1243 fmt_last = *filter_chain_GetFmtOut( id->p_f_chain );
1248 /* FIXME FIXME FIXME WHAT DOES THIS CODE DO? LOOKS LIKE IT'S RANDOMLY TRYING
1249 TO CHAIN A BUNCH OF AUDIO FILTERS */
1250 for( i = 0; i < TRANSCODE_FILTERS; i++ )
1252 if( (fmt_last.audio.i_channels !=
1253 id->p_encoder->fmt_in.audio.i_channels) ||
1254 (fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate) ||
1255 (fmt_last.i_codec != id->p_encoder->fmt_in.i_codec) )
1257 id->pp_filter[id->i_filter] =
1258 transcode_audio_filter_new( p_stream, id, &fmt_last,
1259 &id->p_encoder->fmt_in, NULL );
1261 if( id->pp_filter[id->i_filter] )
1269 /* Final checks to see if conversions were successful */
1270 if( fmt_last.i_codec != id->p_encoder->fmt_in.i_codec )
1272 msg_Err( p_stream, "no audio filter found (%4.4s->%4.4s)",
1273 (char *)&fmt_last.i_codec,
1274 (char *)&id->p_encoder->fmt_in.i_codec );
1275 transcode_audio_close( id );
1276 return VLC_EGENERIC;
1279 /* Load user specified audio filters now */
1280 if( p_sys->psz_af2 )
1282 id->p_uf_chain = filter_chain_New( p_stream, "audio filter2", false,
1283 transcode_audio_filter_allocation_init, NULL, NULL );
1284 filter_chain_Reset( id->p_uf_chain, &fmt_last, &id->p_encoder->fmt_in );
1285 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_af2 );
1288 if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels )
1291 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1292 id->p_encoder->p_module = NULL;
1294 /* This might work, but only if the encoder is restarted */
1295 id->p_encoder->fmt_in.audio.i_channels = fmt_last.audio.i_channels;
1296 id->p_encoder->fmt_out.audio.i_channels = fmt_last.audio.i_channels;
1298 id->p_encoder->fmt_in.audio.i_physical_channels =
1299 id->p_encoder->fmt_in.audio.i_original_channels =
1300 fmt_last.audio.i_physical_channels;
1301 id->p_encoder->fmt_out.audio.i_physical_channels =
1302 id->p_encoder->fmt_out.audio.i_original_channels =
1303 fmt_last.audio.i_physical_channels;
1305 msg_Dbg( p_stream, "number of audio channels for mixing changed, "
1306 "trying to reopen the encoder for mixing %i to %i channels",
1307 fmt_last.audio.i_channels,
1308 id->p_encoder->fmt_in.audio.i_channels );
1310 /* reload encoder */
1311 id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1312 id->p_encoder->p_module =
1313 module_Need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1314 if( !id->p_encoder->p_module )
1316 msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)",
1317 p_sys->psz_aenc ? p_sys->psz_aenc : "any",
1318 (char *)&p_sys->i_acodec );
1319 transcode_audio_close( id );
1320 return VLC_EGENERIC;
1322 id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1323 id->p_encoder->fmt_in.audio.i_bitspersample =
1324 audio_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1326 msg_Err( p_stream, "no audio filter found for mixing from"
1327 " %i to %i channels", fmt_last.audio.i_channels,
1328 id->p_encoder->fmt_in.audio.i_channels );
1330 transcode_audio_close( id );
1331 return VLC_EGENERIC;
1335 if( fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1337 msg_Err( p_stream, "no audio filter found for resampling from"
1338 " %iHz to %iHz", fmt_last.audio.i_rate,
1339 id->p_encoder->fmt_in.audio.i_rate );
1341 /* FIXME : this might work, but only if the encoder is restarted */
1342 id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;
1343 id->p_encoder->fmt_out.audio.i_rate = fmt_last.audio.i_rate;
1345 transcode_audio_close( id );
1346 return VLC_EGENERIC;
1350 /* FIXME: Hack for mp3 transcoding support */
1351 if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC( 'm','p','3',' ' ) )
1352 id->p_encoder->fmt_out.i_codec = VLC_FOURCC( 'm','p','g','a' );
1357 static void transcode_audio_close( sout_stream_id_t *id )
1359 audio_timer_close( id->p_encoder );
1362 if( id->p_decoder->p_module )
1363 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1364 id->p_decoder->p_module = NULL;
1367 if( id->p_encoder->p_module )
1368 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1369 id->p_encoder->p_module = NULL;
1373 filter_chain_Delete( id->p_f_chain );
1374 if( id->p_uf_chain )
1375 filter_chain_Delete( id->p_uf_chain );
1378 static int transcode_audio_process( sout_stream_t *p_stream,
1379 sout_stream_id_t *id,
1380 block_t *in, block_t **out )
1382 sout_stream_sys_t *p_sys = p_stream->p_sys;
1383 aout_buffer_t *p_audio_buf;
1384 block_t *p_block, *p_audio_block;
1387 while( (p_audio_buf = id->p_decoder->pf_decode_audio( id->p_decoder,
1390 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_AUDIO, 1 );
1391 if( p_sys->b_master_sync )
1393 mtime_t i_dts = date_Get( &id->interpolated_pts ) + 1;
1394 if ( p_audio_buf->start_date - i_dts > MASTER_SYNC_MAX_DRIFT
1395 || p_audio_buf->start_date - i_dts < -MASTER_SYNC_MAX_DRIFT )
1397 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1398 date_Set( &id->interpolated_pts, p_audio_buf->start_date );
1399 i_dts = p_audio_buf->start_date + 1;
1401 p_sys->i_master_drift = p_audio_buf->start_date - i_dts;
1402 date_Increment( &id->interpolated_pts, p_audio_buf->i_nb_samples );
1403 p_audio_buf->start_date -= p_sys->i_master_drift;
1404 p_audio_buf->end_date -= p_sys->i_master_drift;
1407 p_audio_block = p_audio_buf->p_sys;
1408 p_audio_block->i_buffer = p_audio_buf->i_nb_bytes;
1409 p_audio_block->i_dts = p_audio_block->i_pts =
1410 p_audio_buf->start_date;
1411 p_audio_block->i_length = p_audio_buf->end_date -
1412 p_audio_buf->start_date;
1413 p_audio_block->i_samples = p_audio_buf->i_nb_samples;
1415 /* Run filter chain */
1416 p_audio_block = filter_chain_AudioFilter( id->p_f_chain, p_audio_block );
1417 if( id->p_uf_chain )
1418 p_audio_block = filter_chain_AudioFilter( id->p_uf_chain, p_audio_block );
1419 assert( p_audio_block );
1421 p_audio_buf->p_buffer = p_audio_block->p_buffer;
1422 p_audio_buf->i_nb_bytes = p_audio_block->i_buffer;
1423 p_audio_buf->i_nb_samples = p_audio_block->i_samples;
1424 p_audio_buf->start_date = p_audio_block->i_dts;
1425 p_audio_buf->end_date = p_audio_block->i_dts + p_audio_block->i_length;
1427 audio_timer_start( id->p_encoder );
1428 p_block = id->p_encoder->pf_encode_audio( id->p_encoder, p_audio_buf );
1429 audio_timer_stop( id->p_encoder );
1431 block_ChainAppend( out, p_block );
1432 block_Release( p_audio_block );
1433 free( p_audio_buf );
1439 static void audio_release_buffer( aout_buffer_t *p_buffer )
1441 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1445 static aout_buffer_t *audio_new_buffer( decoder_t *p_dec, int i_samples )
1447 aout_buffer_t *p_buffer;
1451 if( p_dec->fmt_out.audio.i_bitspersample )
1453 i_size = i_samples * p_dec->fmt_out.audio.i_bitspersample / 8 *
1454 p_dec->fmt_out.audio.i_channels;
1456 else if( p_dec->fmt_out.audio.i_bytes_per_frame &&
1457 p_dec->fmt_out.audio.i_frame_length )
1459 i_size = i_samples * p_dec->fmt_out.audio.i_bytes_per_frame /
1460 p_dec->fmt_out.audio.i_frame_length;
1464 i_size = i_samples * 4 * p_dec->fmt_out.audio.i_channels;
1467 p_buffer = malloc( sizeof(aout_buffer_t) );
1468 if( !p_buffer ) return NULL;
1469 p_buffer->b_discontinuity = false;
1470 p_buffer->pf_release = audio_release_buffer;
1471 p_buffer->p_sys = p_block = block_New( p_dec, i_size );
1473 p_buffer->p_buffer = p_block->p_buffer;
1474 p_buffer->i_size = p_buffer->i_nb_bytes = p_block->i_buffer;
1475 p_buffer->i_nb_samples = i_samples;
1476 p_block->i_samples = i_samples;
1481 static void audio_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
1484 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1492 static int transcode_video_filter_allocation_init( filter_t *p_filter,
1495 sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_data;
1498 p_filter->pf_vout_buffer_new = video_new_buffer_filter;
1499 p_filter->pf_vout_buffer_del = video_del_buffer_filter;
1501 p_filter->p_owner = malloc( sizeof(filter_owner_sys_t) );
1502 if( !p_filter->p_owner )
1503 return VLC_EGENERIC;
1505 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1506 p_filter->p_owner->pp_pics[i] = 0;
1507 p_filter->p_owner->p_sys = p_sys;
1512 static void transcode_video_filter_allocation_clear( filter_t *p_filter )
1516 /* Clean-up pictures ring buffer */
1517 for( j = 0; j < PICTURE_RING_SIZE; j++ )
1519 if( p_filter->p_owner->pp_pics[j] )
1520 video_del_buffer( VLC_OBJECT(p_filter),
1521 p_filter->p_owner->pp_pics[j] );
1523 free( p_filter->p_owner );
1526 static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
1528 sout_stream_sys_t *p_sys = p_stream->p_sys;
1532 * Initialization of decoder structures
1534 id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1535 id->p_decoder->fmt_out.i_extra = 0;
1536 id->p_decoder->fmt_out.p_extra = 0;
1537 id->p_decoder->pf_decode_video = NULL;
1538 id->p_decoder->pf_get_cc = NULL;
1539 id->p_decoder->pf_get_cc = 0;
1540 id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
1541 id->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder;
1542 id->p_decoder->pf_picture_link = video_link_picture_decoder;
1543 id->p_decoder->pf_picture_unlink = video_unlink_picture_decoder;
1544 id->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) );
1545 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1546 id->p_decoder->p_owner->pp_pics[i] = 0;
1547 id->p_decoder->p_owner->p_sys = p_sys;
1548 /* id->p_decoder->p_cfg = p_sys->p_video_cfg; */
1550 id->p_decoder->p_module =
1551 module_Need( id->p_decoder, "decoder", "$codec", 0 );
1553 if( !id->p_decoder->p_module )
1555 msg_Err( p_stream, "cannot find video decoder" );
1556 return VLC_EGENERIC;
1561 * Because some info about the decoded input will only be available
1562 * once the first frame is decoded, we actually only test the availability
1563 * of the encoder here.
1566 /* Initialization of encoder format structures */
1567 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1568 id->p_decoder->fmt_out.i_codec );
1569 id->p_encoder->fmt_in.video.i_chroma = id->p_decoder->fmt_out.i_codec;
1571 /* The dimensions will be set properly later on.
1572 * Just put sensible values so we can test an encoder is available. */
1573 id->p_encoder->fmt_in.video.i_width =
1574 id->p_encoder->fmt_out.video.i_width ?:
1575 id->p_decoder->fmt_in.video.i_width ?: 16;
1576 id->p_encoder->fmt_in.video.i_height =
1577 id->p_encoder->fmt_out.video.i_height ?:
1578 id->p_decoder->fmt_in.video.i_height ?: 16;
1579 id->p_encoder->fmt_in.video.i_frame_rate = ENC_FRAMERATE;
1580 id->p_encoder->fmt_in.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1582 id->p_encoder->i_threads = p_sys->i_threads;
1583 id->p_encoder->p_cfg = p_sys->p_video_cfg;
1585 id->p_encoder->p_module =
1586 module_Need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1587 if( !id->p_encoder->p_module )
1589 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1590 p_sys->psz_venc ? p_sys->psz_venc : "any",
1591 (char *)&p_sys->i_vcodec );
1592 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1593 id->p_decoder->p_module = 0;
1594 return VLC_EGENERIC;
1597 /* Close the encoder.
1598 * We'll open it only when we have the first frame. */
1599 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1600 if( id->p_encoder->fmt_out.p_extra )
1602 free( id->p_encoder->fmt_out.p_extra );
1603 id->p_encoder->fmt_out.p_extra = NULL;
1604 id->p_encoder->fmt_out.i_extra = 0;
1606 id->p_encoder->p_module = NULL;
1608 if( p_sys->i_threads >= 1 )
1610 int i_priority = p_sys->b_high_priority ? VLC_THREAD_PRIORITY_OUTPUT :
1611 VLC_THREAD_PRIORITY_VIDEO;
1612 p_sys->id_video = id;
1613 vlc_mutex_init( &p_sys->lock_out );
1614 vlc_cond_init( p_stream, &p_sys->cond );
1615 memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) );
1616 p_sys->i_first_pic = 0;
1617 p_sys->i_last_pic = 0;
1618 p_sys->p_buffers = NULL;
1619 p_sys->b_die = p_sys->b_error = 0;
1620 if( vlc_thread_create( p_sys, "encoder", EncoderThread, i_priority,
1623 msg_Err( p_stream, "cannot spawn encoder thread" );
1624 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1625 id->p_decoder->p_module = 0;
1626 return VLC_EGENERIC;
1633 static int transcode_video_encoder_open( sout_stream_t *p_stream,
1634 sout_stream_id_t *id )
1636 sout_stream_sys_t *p_sys = p_stream->p_sys;
1638 /* Calculate scaling
1639 * width/height of source */
1640 int i_src_width = id->p_decoder->fmt_out.video.i_width;
1641 int i_src_height = id->p_decoder->fmt_out.video.i_height;
1643 /* with/height scaling */
1644 float f_scale_width = 1;
1645 float f_scale_height = 1;
1647 /* width/height of output stream */
1652 float f_aspect = (float)id->p_decoder->fmt_out.video.i_aspect /
1655 msg_Dbg( p_stream, "decoder aspect is %i:%i",
1656 id->p_decoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1658 /* Change f_aspect from source frame to source pixel */
1659 f_aspect = f_aspect * i_src_height / i_src_width;
1660 msg_Dbg( p_stream, "source pixel aspect is %f:1", f_aspect );
1662 /* Calculate scaling factor for specified parameters */
1663 if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1664 id->p_encoder->fmt_out.video.i_height <= 0 && p_sys->f_scale )
1666 /* Global scaling. Make sure width will remain a factor of 16 */
1669 int i_new_width = i_src_width * p_sys->f_scale;
1671 if( i_new_width % 16 <= 7 && i_new_width >= 16 )
1672 i_new_width -= i_new_width % 16;
1674 i_new_width += 16 - i_new_width % 16;
1676 f_real_scale = (float)( i_new_width ) / (float) i_src_width;
1678 i_new_height = __MAX( 16, i_src_height * (float)f_real_scale );
1680 f_scale_width = f_real_scale;
1681 f_scale_height = (float) i_new_height / (float) i_src_height;
1683 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1684 id->p_encoder->fmt_out.video.i_height <= 0 )
1686 /* Only width specified */
1687 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1688 f_scale_height = f_scale_width;
1690 else if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1691 id->p_encoder->fmt_out.video.i_height > 0 )
1693 /* Only height specified */
1694 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1695 f_scale_width = f_scale_height;
1697 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1698 id->p_encoder->fmt_out.video.i_height > 0 )
1700 /* Width and height specified */
1701 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1702 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1705 /* check maxwidth and maxheight
1707 if( p_sys->i_maxwidth && f_scale_width > (float)p_sys->i_maxwidth /
1710 f_scale_width = (float)p_sys->i_maxwidth / i_src_width;
1713 if( p_sys->i_maxheight && f_scale_height > (float)p_sys->i_maxheight /
1716 f_scale_height = (float)p_sys->i_maxheight / i_src_height;
1720 /* Change aspect ratio from source pixel to scaled pixel */
1721 f_aspect = f_aspect * f_scale_height / f_scale_width;
1722 msg_Dbg( p_stream, "scaled pixel aspect is %f:1", f_aspect );
1724 /* f_scale_width and f_scale_height are now final */
1725 /* Calculate width, height from scaling
1726 * Make sure its multiple of 2
1728 i_dst_width = 2 * (int)(f_scale_width*i_src_width/2+0.5);
1729 i_dst_height = 2 * (int)(f_scale_height*i_src_height/2+0.5);
1731 /* Change aspect ratio from scaled pixel to output frame */
1732 f_aspect = f_aspect * i_dst_width / i_dst_height;
1734 /* Store calculated values */
1735 id->p_encoder->fmt_out.video.i_width = i_dst_width;
1736 id->p_encoder->fmt_out.video.i_height = i_dst_height;
1738 id->p_encoder->fmt_in.video.i_width = i_dst_width;
1739 id->p_encoder->fmt_in.video.i_height = i_dst_height;
1741 msg_Dbg( p_stream, "source %ix%i, destination %ix%i",
1742 i_src_width, i_src_height,
1743 i_dst_width, i_dst_height
1746 /* Handle frame rate conversion */
1747 if( !id->p_encoder->fmt_out.video.i_frame_rate ||
1748 !id->p_encoder->fmt_out.video.i_frame_rate_base )
1750 if( id->p_decoder->fmt_out.video.i_frame_rate &&
1751 id->p_decoder->fmt_out.video.i_frame_rate_base )
1753 id->p_encoder->fmt_out.video.i_frame_rate =
1754 id->p_decoder->fmt_out.video.i_frame_rate;
1755 id->p_encoder->fmt_out.video.i_frame_rate_base =
1756 id->p_decoder->fmt_out.video.i_frame_rate_base;
1760 /* Pick a sensible default value */
1761 id->p_encoder->fmt_out.video.i_frame_rate = ENC_FRAMERATE;
1762 id->p_encoder->fmt_out.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1766 id->p_encoder->fmt_in.video.i_frame_rate =
1767 id->p_encoder->fmt_out.video.i_frame_rate;
1768 id->p_encoder->fmt_in.video.i_frame_rate_base =
1769 id->p_encoder->fmt_out.video.i_frame_rate_base;
1771 date_Init( &id->interpolated_pts,
1772 id->p_encoder->fmt_out.video.i_frame_rate,
1773 id->p_encoder->fmt_out.video.i_frame_rate_base );
1775 /* Check whether a particular aspect ratio was requested */
1776 if( !id->p_encoder->fmt_out.video.i_aspect )
1778 id->p_encoder->fmt_out.video.i_aspect =
1779 (int)( f_aspect * VOUT_ASPECT_FACTOR + 0.5 );
1781 id->p_encoder->fmt_in.video.i_aspect =
1782 id->p_encoder->fmt_out.video.i_aspect;
1784 msg_Dbg( p_stream, "encoder aspect is %i:%i",
1785 id->p_encoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1787 id->p_encoder->p_module =
1788 module_Need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1789 if( !id->p_encoder->p_module )
1791 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1792 p_sys->psz_venc ? p_sys->psz_venc : "any",
1793 (char *)&p_sys->i_vcodec );
1794 return VLC_EGENERIC;
1797 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1799 /* Hack for mp2v/mp1v transcoding support */
1800 if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','1','v') ||
1801 id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','2','v') )
1803 id->p_encoder->fmt_out.i_codec = VLC_FOURCC('m','p','g','v');
1806 id->id = p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out,
1807 &id->p_encoder->fmt_out );
1810 msg_Err( p_stream, "cannot add this stream" );
1811 return VLC_EGENERIC;
1817 static void transcode_video_close( sout_stream_t *p_stream,
1818 sout_stream_id_t *id )
1822 if( p_stream->p_sys->i_threads >= 1 )
1824 vlc_mutex_lock( &p_stream->p_sys->lock_out );
1825 vlc_object_kill( p_stream->p_sys );
1826 vlc_cond_signal( &p_stream->p_sys->cond );
1827 vlc_mutex_unlock( &p_stream->p_sys->lock_out );
1828 vlc_thread_join( p_stream->p_sys );
1829 vlc_mutex_destroy( &p_stream->p_sys->lock_out );
1830 vlc_cond_destroy( &p_stream->p_sys->cond );
1833 video_timer_close( id->p_encoder );
1836 if( id->p_decoder->p_module )
1837 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1839 if( id->p_decoder->p_owner )
1841 /* Clean-up pictures ring buffer */
1842 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1844 if( id->p_decoder->p_owner->pp_pics[i] )
1845 video_del_buffer( VLC_OBJECT(id->p_decoder),
1846 id->p_decoder->p_owner->pp_pics[i] );
1848 free( id->p_decoder->p_owner );
1852 if( id->p_encoder->p_module )
1853 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1857 filter_chain_Delete( id->p_f_chain );
1858 if( id->p_uf_chain )
1859 filter_chain_Delete( id->p_uf_chain );
1862 static int transcode_video_process( sout_stream_t *p_stream,
1863 sout_stream_id_t *id,
1864 block_t *in, block_t **out )
1866 sout_stream_sys_t *p_sys = p_stream->p_sys;
1867 int i_duplicate = 1;
1868 picture_t *p_pic, *p_pic2 = NULL;
1871 while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
1873 subpicture_t *p_subpic = NULL;
1875 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_VIDEO, 1 );
1877 if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )
1879 mtime_t current_date = mdate();
1880 if( current_date + 50000 > p_pic->date )
1882 msg_Dbg( p_stream, "late picture skipped (%"PRId64")",
1883 current_date + 50000 - p_pic->date );
1884 p_pic->pf_release( p_pic );
1889 if( p_sys->b_master_sync )
1891 mtime_t i_video_drift;
1892 mtime_t i_master_drift = p_sys->i_master_drift;
1895 i_pts = date_Get( &id->interpolated_pts ) + 1;
1896 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1897 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
1899 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1900 date_Set( &id->interpolated_pts, p_pic->date );
1901 i_pts = p_pic->date + 1;
1903 i_video_drift = p_pic->date - i_pts;
1906 /* Set the pts of the frame being encoded */
1907 p_pic->date = i_pts;
1909 if( i_video_drift < (i_master_drift - 50000) )
1912 msg_Dbg( p_stream, "dropping frame (%i)",
1913 (int)(i_video_drift - i_master_drift) );
1915 p_pic->pf_release( p_pic );
1918 else if( i_video_drift > (i_master_drift + 50000) )
1921 msg_Dbg( p_stream, "adding frame (%i)",
1922 (int)(i_video_drift - i_master_drift) );
1928 if( !id->p_encoder->p_module )
1930 if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS )
1932 p_pic->pf_release( p_pic );
1933 transcode_video_close( p_stream, id );
1934 id->b_transcode = false;
1935 return VLC_EGENERIC;
1938 id->p_f_chain = filter_chain_New( p_stream, "video filter2",
1940 transcode_video_filter_allocation_init,
1941 transcode_video_filter_allocation_clear,
1945 if( p_stream->p_sys->b_deinterlace )
1947 filter_chain_AppendFilter( id->p_f_chain,
1948 p_sys->psz_deinterlace,
1949 p_sys->p_deinterlace_cfg,
1950 &id->p_decoder->fmt_out,
1951 &id->p_decoder->fmt_out );
1954 /* Take care of the scaling and chroma conversions */
1955 if( ( id->p_decoder->fmt_out.video.i_chroma !=
1956 id->p_encoder->fmt_in.video.i_chroma ) ||
1957 ( id->p_decoder->fmt_out.video.i_width !=
1958 id->p_encoder->fmt_in.video.i_width ) ||
1959 ( id->p_decoder->fmt_out.video.i_height !=
1960 id->p_encoder->fmt_in.video.i_height ) )
1962 filter_chain_AppendFilter( id->p_f_chain,
1964 &id->p_decoder->fmt_out,
1965 &id->p_encoder->fmt_in );
1968 if( p_sys->psz_vf2 )
1970 id->p_uf_chain = filter_chain_New( p_stream, "video filter2",
1972 transcode_video_filter_allocation_init,
1973 transcode_video_filter_allocation_clear,
1975 filter_chain_Reset( id->p_uf_chain, &id->p_decoder->fmt_out,
1976 &id->p_encoder->fmt_in );
1977 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_vf2 );
1981 /* Run filter chain */
1983 p_pic = filter_chain_VideoFilter( id->p_f_chain, p_pic );
1989 /* Check if we have a subpicture to overlay */
1992 p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date,
1993 false /* Fixme: check if stream is paused */ );
1994 /* TODO: get another pic */
1997 /* Overlay subpicture */
2000 int i_scale_width, i_scale_height;
2001 video_format_t *p_fmt;
2003 i_scale_width = id->p_encoder->fmt_in.video.i_width * 1000 /
2004 id->p_decoder->fmt_out.video.i_width;
2005 i_scale_height = id->p_encoder->fmt_in.video.i_height * 1000 /
2006 id->p_decoder->fmt_out.video.i_height;
2008 if( p_pic->i_refcount && !filter_chain_GetLength( id->p_f_chain ) )
2010 /* We can't modify the picture, we need to duplicate it */
2011 picture_t *p_tmp = video_new_buffer_decoder( id->p_decoder );
2014 vout_CopyPicture( p_stream, p_tmp, p_pic );
2015 p_pic->pf_release( p_pic );
2020 *p_fmt = filter_chain_GetFmtOut( id->p_f_chain )->video;
2022 /* FIXME (shouldn't have to be done here) */
2023 p_fmt->i_sar_num = p_fmt->i_aspect *
2024 p_fmt->i_height / p_fmt->i_width;
2025 p_fmt->i_sar_den = VOUT_ASPECT_FACTOR;
2027 spu_RenderSubpictures( p_sys->p_spu, p_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;