1 /*****************************************************************************
2 * transcode.c: transcoding stream output module
3 *****************************************************************************
4 * Copyright (C) 2003-2008 the VideoLAN team
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8 * Gildas Bazin <gbazin@videolan.org>
9 * Jean-Paul Saman <jpsaman #_at_# m2x dot nl>
10 * Antoine Cellerier <dionoea at videolan dot org>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25 *****************************************************************************/
27 /*****************************************************************************
29 *****************************************************************************/
34 #include <vlc_common.h>
35 #include <vlc_plugin.h>
36 #include <vlc_input.h>
40 #include <vlc_codec.h>
41 #include <vlc_block.h>
42 #include <vlc_filter.h>
47 #define MASTER_SYNC_MAX_DRIFT 100000
51 /*****************************************************************************
53 *****************************************************************************/
54 #define VENC_TEXT N_("Video encoder")
55 #define VENC_LONGTEXT N_( \
56 "This is the video encoder module that will be used (and its associated "\
58 #define VCODEC_TEXT N_("Destination video codec")
59 #define VCODEC_LONGTEXT N_( \
60 "This is the video codec that will be used.")
61 #define VB_TEXT N_("Video bitrate")
62 #define VB_LONGTEXT N_( \
63 "Target bitrate of the transcoded video stream." )
64 #define SCALE_TEXT N_("Video scaling")
65 #define SCALE_LONGTEXT N_( \
66 "Scale factor to apply to the video while transcoding (eg: 0.25)")
67 #define FPS_TEXT N_("Video frame-rate")
68 #define FPS_LONGTEXT N_( \
69 "Target output frame rate for the video stream." )
70 #define DEINTERLACE_TEXT N_("Deinterlace video")
71 #define DEINTERLACE_LONGTEXT N_( \
72 "Deinterlace the video before encoding." )
73 #define DEINTERLACE_MODULE_TEXT N_("Deinterlace module")
74 #define DEINTERLACE_MODULE_LONGTEXT N_( \
75 "Specify the deinterlace module to use." )
76 #define WIDTH_TEXT N_("Video width")
77 #define WIDTH_LONGTEXT N_( \
78 "Output video width." )
79 #define HEIGHT_TEXT N_("Video height")
80 #define HEIGHT_LONGTEXT N_( \
81 "Output video height." )
82 #define MAXWIDTH_TEXT N_("Maximum video width")
83 #define MAXWIDTH_LONGTEXT N_( \
84 "Maximum output video width." )
85 #define MAXHEIGHT_TEXT N_("Maximum video height")
86 #define MAXHEIGHT_LONGTEXT N_( \
87 "Maximum output video height." )
88 #define VFILTER_TEXT N_("Video filter")
89 #define VFILTER_LONGTEXT N_( \
90 "Video filters will be applied to the video streams (after overlays " \
91 "are applied). You must enter a comma-separated list of filters." )
93 #define AENC_TEXT N_("Audio encoder")
94 #define AENC_LONGTEXT N_( \
95 "This is the audio encoder module that will be used (and its associated "\
97 #define ACODEC_TEXT N_("Destination audio codec")
98 #define ACODEC_LONGTEXT N_( \
99 "This is the audio codec that will be used.")
100 #define AB_TEXT N_("Audio bitrate")
101 #define AB_LONGTEXT N_( \
102 "Target bitrate of the transcoded audio stream." )
103 #define ARATE_TEXT N_("Audio sample rate")
104 #define ARATE_LONGTEXT N_( \
105 "Sample rate of the transcoded audio stream (11250, 22500, 44100 or 48000).")
106 #define ACHANS_TEXT N_("Audio channels")
107 #define ACHANS_LONGTEXT N_( \
108 "Number of audio channels in the transcoded streams." )
109 #define AFILTER_TEXT N_("Audio filter")
110 #define AFILTER_LONGTEXT N_( \
111 "Audio filters will be applied to the audio streams (after conversion " \
112 "filters are applied). You must enter a comma-separated list of filters." )
114 #define SENC_TEXT N_("Subtitles encoder")
115 #define SENC_LONGTEXT N_( \
116 "This is the subtitles encoder module that will be used (and its " \
117 "associated options)." )
118 #define SCODEC_TEXT N_("Destination subtitles codec")
119 #define SCODEC_LONGTEXT N_( \
120 "This is the subtitles codec that will be used." )
122 #define SFILTER_TEXT N_("Overlays")
123 #define SFILTER_LONGTEXT N_( \
124 "This allows you to add overlays (also known as \"subpictures\" on the "\
125 "transcoded video stream. The subpictures produced by the filters will "\
126 "be overlayed directly onto the video. You must specify a comma-separated "\
127 "list of subpicture modules" )
129 #define OSD_TEXT N_("OSD menu")
130 #define OSD_LONGTEXT N_(\
131 "Stream the On Screen Display menu (using the osdmenu subpicture module)." )
133 #define THREADS_TEXT N_("Number of threads")
134 #define THREADS_LONGTEXT N_( \
135 "Number of threads used for the transcoding." )
136 #define HP_TEXT N_("High priority")
137 #define HP_LONGTEXT N_( \
138 "Runs the optional encoder thread at the OUTPUT priority instead of " \
141 #define ASYNC_TEXT N_("Synchronise on audio track")
142 #define ASYNC_LONGTEXT N_( \
143 "This option will drop/duplicate video frames to synchronise the video " \
144 "track on the audio track." )
146 #define HURRYUP_TEXT N_( "Hurry up" )
147 #define HURRYUP_LONGTEXT N_( "The transcoder will drop frames if your CPU " \
148 "can't keep up with the encoding rate." )
150 static const char *const ppsz_deinterlace_type[] =
152 "deinterlace", "ffmpeg-deinterlace"
155 static int Open ( vlc_object_t * );
156 static void Close( vlc_object_t * );
158 #define SOUT_CFG_PREFIX "sout-transcode-"
161 set_shortname( N_("Transcode"))
162 set_description( N_("Transcode stream output") )
163 set_capability( "sout stream", 50 )
164 add_shortcut( "transcode" )
165 set_callbacks( Open, Close )
166 set_category( CAT_SOUT )
167 set_subcategory( SUBCAT_SOUT_STREAM )
168 set_section( N_("Video"), NULL )
169 add_string( SOUT_CFG_PREFIX "venc", NULL, NULL, VENC_TEXT,
170 VENC_LONGTEXT, false );
171 add_string( SOUT_CFG_PREFIX "vcodec", NULL, NULL, VCODEC_TEXT,
172 VCODEC_LONGTEXT, false );
173 add_integer( SOUT_CFG_PREFIX "vb", 800 * 1000, NULL, VB_TEXT,
174 VB_LONGTEXT, false );
175 add_float( SOUT_CFG_PREFIX "scale", 1, NULL, SCALE_TEXT,
176 SCALE_LONGTEXT, false );
177 add_float( SOUT_CFG_PREFIX "fps", 0, NULL, FPS_TEXT,
178 FPS_LONGTEXT, false );
179 add_bool( SOUT_CFG_PREFIX "hurry-up", true, NULL, HURRYUP_TEXT,
180 HURRYUP_LONGTEXT, false );
181 add_bool( SOUT_CFG_PREFIX "deinterlace", 0, NULL, DEINTERLACE_TEXT,
182 DEINTERLACE_LONGTEXT, false );
183 add_string( SOUT_CFG_PREFIX "deinterlace-module", "deinterlace", NULL,
184 DEINTERLACE_MODULE_TEXT, DEINTERLACE_MODULE_LONGTEXT,
186 change_string_list( ppsz_deinterlace_type, 0, 0 );
187 add_integer( SOUT_CFG_PREFIX "width", 0, NULL, WIDTH_TEXT,
188 WIDTH_LONGTEXT, true );
189 add_integer( SOUT_CFG_PREFIX "height", 0, NULL, HEIGHT_TEXT,
190 HEIGHT_LONGTEXT, true );
191 add_integer( SOUT_CFG_PREFIX "maxwidth", 0, NULL, MAXWIDTH_TEXT,
192 MAXWIDTH_LONGTEXT, true );
193 add_integer( SOUT_CFG_PREFIX "maxheight", 0, NULL, MAXHEIGHT_TEXT,
194 MAXHEIGHT_LONGTEXT, true );
195 add_module_list( SOUT_CFG_PREFIX "vfilter", "video filter2",
197 VFILTER_TEXT, VFILTER_LONGTEXT, false );
199 set_section( N_("Audio"), NULL )
200 add_string( SOUT_CFG_PREFIX "aenc", NULL, NULL, AENC_TEXT,
201 AENC_LONGTEXT, false );
202 add_string( SOUT_CFG_PREFIX "acodec", NULL, NULL, ACODEC_TEXT,
203 ACODEC_LONGTEXT, false );
204 add_integer( SOUT_CFG_PREFIX "ab", 0, NULL, AB_TEXT,
205 AB_LONGTEXT, false );
206 add_integer( SOUT_CFG_PREFIX "channels", 0, NULL, ACHANS_TEXT,
207 ACHANS_LONGTEXT, false );
208 add_integer( SOUT_CFG_PREFIX "samplerate", 0, NULL, ARATE_TEXT,
209 ARATE_LONGTEXT, true );
210 add_bool( SOUT_CFG_PREFIX "audio-sync", 0, NULL, ASYNC_TEXT,
211 ASYNC_LONGTEXT, false );
212 add_module_list( SOUT_CFG_PREFIX "afilter", "audio filter2",
214 AFILTER_TEXT, AFILTER_LONGTEXT, false );
216 set_section( N_("Overlays/Subtitles"), NULL )
217 add_string( SOUT_CFG_PREFIX "senc", NULL, NULL, SENC_TEXT,
218 SENC_LONGTEXT, false );
219 add_string( SOUT_CFG_PREFIX "scodec", NULL, NULL, SCODEC_TEXT,
220 SCODEC_LONGTEXT, false );
221 add_bool( SOUT_CFG_PREFIX "soverlay", 0, NULL, SCODEC_TEXT,
222 SCODEC_LONGTEXT, false );
223 add_module_list( SOUT_CFG_PREFIX "sfilter", "video filter",
225 SFILTER_TEXT, SFILTER_LONGTEXT, false );
227 set_section( N_("On Screen Display"), NULL )
228 add_bool( SOUT_CFG_PREFIX "osd", 0, NULL, OSD_TEXT,
229 OSD_LONGTEXT, false );
231 set_section( N_("Miscellaneous"), NULL )
232 add_integer( SOUT_CFG_PREFIX "threads", 0, NULL, THREADS_TEXT,
233 THREADS_LONGTEXT, true );
234 add_bool( SOUT_CFG_PREFIX "high-priority", 0, NULL, HP_TEXT, HP_LONGTEXT,
239 static const char *const ppsz_sout_options[] = {
240 "venc", "vcodec", "vb",
241 "scale", "fps", "width", "height", "vfilter", "deinterlace",
242 "deinterlace-module", "threads", "hurry-up", "aenc", "acodec", "ab",
243 "afilter", "samplerate", "channels", "senc", "scodec", "soverlay",
244 "sfilter", "osd", "audio-sync", "high-priority", "maxwidth", "maxheight",
248 /*****************************************************************************
249 * Exported prototypes
250 *****************************************************************************/
251 static sout_stream_id_t *Add ( sout_stream_t *, es_format_t * );
252 static int Del ( sout_stream_t *, sout_stream_id_t * );
253 static int Send( sout_stream_t *, sout_stream_id_t *, block_t* );
255 static int transcode_audio_new ( sout_stream_t *, sout_stream_id_t * );
256 static void transcode_audio_close ( sout_stream_id_t * );
257 static int transcode_audio_process( sout_stream_t *, sout_stream_id_t *,
258 block_t *, block_t ** );
260 static aout_buffer_t *audio_new_buffer( decoder_t *, int );
261 static void audio_del_buffer( decoder_t *, aout_buffer_t * );
263 static int transcode_video_new ( sout_stream_t *, sout_stream_id_t * );
264 static void transcode_video_close ( sout_stream_t *, sout_stream_id_t * );
265 static void transcode_video_encoder_init( sout_stream_t *, sout_stream_id_t *);
266 static int transcode_video_encoder_open( sout_stream_t *, sout_stream_id_t *);
267 static int transcode_video_process( sout_stream_t *, sout_stream_id_t *,
268 block_t *, block_t ** );
270 static void video_del_buffer( vlc_object_t *, picture_t * );
271 static picture_t *video_new_buffer_decoder( decoder_t * );
272 static void video_del_buffer_decoder( decoder_t *, picture_t * );
273 static void video_link_picture_decoder( decoder_t *, picture_t * );
274 static void video_unlink_picture_decoder( decoder_t *, picture_t * );
275 static picture_t *video_new_buffer_filter( filter_t * );
276 static void video_del_buffer_filter( filter_t *, picture_t * );
278 static int transcode_spu_new ( sout_stream_t *, sout_stream_id_t * );
279 static void transcode_spu_close ( sout_stream_id_t * );
280 static int transcode_spu_process( sout_stream_t *, sout_stream_id_t *,
281 block_t *, block_t ** );
283 static int transcode_osd_new ( sout_stream_t *, sout_stream_id_t * );
284 static void transcode_osd_close ( sout_stream_t *, sout_stream_id_t * );
285 static int transcode_osd_process( sout_stream_t *, sout_stream_id_t *,
286 block_t *, block_t ** );
288 static void* EncoderThread( vlc_object_t * p_this );
290 static const int pi_channels_maps[6] =
293 AOUT_CHAN_CENTER, AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
294 AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
295 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
296 | AOUT_CHAN_REARRIGHT,
297 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
298 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
301 #define PICTURE_RING_SIZE 64
302 #define SUBPICTURE_RING_SIZE 20
304 #define ENC_FRAMERATE (25 * 1000 + .5)
305 #define ENC_FRAMERATE_BASE 1000
307 struct sout_stream_sys_t
311 sout_stream_t *p_out;
312 sout_stream_id_t *id_video;
314 vlc_mutex_t lock_out;
316 picture_t * pp_pics[PICTURE_RING_SIZE];
317 int i_first_pic, i_last_pic;
320 vlc_fourcc_t i_acodec; /* codec audio (0 if not transcode) */
322 config_chain_t *p_audio_cfg;
323 uint32_t i_sample_rate;
330 vlc_fourcc_t i_vcodec; /* codec video (0 if not transcode) */
332 config_chain_t *p_video_cfg;
336 unsigned int i_width, i_maxwidth;
337 unsigned int i_height, i_maxheight;
339 char *psz_deinterlace;
340 config_chain_t *p_deinterlace_cfg;
342 bool b_high_priority;
348 vlc_fourcc_t i_scodec; /* codec spu (0 if not transcode) */
351 config_chain_t *p_spu_cfg;
355 vlc_fourcc_t i_osdcodec; /* codec osd menu (0 if not transcode) */
357 config_chain_t *p_osd_cfg;
358 bool b_osd; /* true when osd es is registered */
362 mtime_t i_master_drift;
365 struct decoder_owner_sys_t
367 picture_t *pp_pics[PICTURE_RING_SIZE];
368 sout_stream_sys_t *p_sys;
370 struct filter_owner_sys_t
372 picture_t *pp_pics[PICTURE_RING_SIZE];
373 sout_stream_sys_t *p_sys;
376 /*****************************************************************************
378 *****************************************************************************/
379 static int Open( vlc_object_t *p_this )
381 sout_stream_t *p_stream = (sout_stream_t*)p_this;
382 sout_stream_sys_t *p_sys;
385 p_sys = vlc_object_create( p_this, sizeof( sout_stream_sys_t ) );
387 p_sys->p_out = sout_StreamNew( p_stream->p_sout, p_stream->psz_next );
390 msg_Err( p_stream, "cannot create chain" );
391 vlc_object_release( p_sys );
395 p_sys->i_master_drift = 0;
397 config_ChainParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options,
400 /* Audio transcoding parameters */
401 var_Get( p_stream, SOUT_CFG_PREFIX "aenc", &val );
402 p_sys->psz_aenc = NULL;
403 p_sys->p_audio_cfg = NULL;
404 if( val.psz_string && *val.psz_string )
407 psz_next = config_ChainCreate( &p_sys->psz_aenc, &p_sys->p_audio_cfg,
411 free( val.psz_string );
413 var_Get( p_stream, SOUT_CFG_PREFIX "acodec", &val );
415 if( val.psz_string && *val.psz_string )
418 memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) );
419 p_sys->i_acodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
421 free( val.psz_string );
423 var_Get( p_stream, SOUT_CFG_PREFIX "ab", &val );
424 p_sys->i_abitrate = val.i_int;
425 if( p_sys->i_abitrate < 4000 ) p_sys->i_abitrate *= 1000;
427 var_Get( p_stream, SOUT_CFG_PREFIX "samplerate", &val );
428 p_sys->i_sample_rate = val.i_int;
430 var_Get( p_stream, SOUT_CFG_PREFIX "channels", &val );
431 p_sys->i_channels = val.i_int;
433 if( p_sys->i_acodec )
435 if( p_sys->i_acodec == VLC_FOURCC('m','p','3',0) &&
436 p_sys->i_channels > 2 )
438 msg_Warn( p_stream, "%d channels invalid for mp3, forcing to 2",
440 p_sys->i_channels = 2;
442 msg_Dbg( p_stream, "codec audio=%4.4s %dHz %d channels %dKb/s",
443 (char *)&p_sys->i_acodec, p_sys->i_sample_rate,
444 p_sys->i_channels, p_sys->i_abitrate / 1000 );
447 var_Get( p_stream, SOUT_CFG_PREFIX "afilter", &val );
448 if( val.psz_string && *val.psz_string )
449 p_sys->psz_af2 = val.psz_string;
452 free( val.psz_string );
453 p_sys->psz_af2 = NULL;
456 /* Video transcoding parameters */
457 var_Get( p_stream, SOUT_CFG_PREFIX "venc", &val );
458 p_sys->psz_venc = NULL;
459 p_sys->p_video_cfg = NULL;
460 if( val.psz_string && *val.psz_string )
463 psz_next = config_ChainCreate( &p_sys->psz_venc, &p_sys->p_video_cfg,
467 free( val.psz_string );
469 var_Get( p_stream, SOUT_CFG_PREFIX "vcodec", &val );
471 if( val.psz_string && *val.psz_string )
474 memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) );
475 p_sys->i_vcodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
477 free( val.psz_string );
479 var_Get( p_stream, SOUT_CFG_PREFIX "vb", &val );
480 p_sys->i_vbitrate = val.i_int;
481 if( p_sys->i_vbitrate < 16000 ) p_sys->i_vbitrate *= 1000;
483 var_Get( p_stream, SOUT_CFG_PREFIX "scale", &val );
484 p_sys->f_scale = val.f_float;
486 var_Get( p_stream, SOUT_CFG_PREFIX "fps", &val );
487 p_sys->f_fps = val.f_float;
489 var_Get( p_stream, SOUT_CFG_PREFIX "hurry-up", &val );
490 p_sys->b_hurry_up = val.b_bool;
492 var_Get( p_stream, SOUT_CFG_PREFIX "width", &val );
493 p_sys->i_width = val.i_int;
495 var_Get( p_stream, SOUT_CFG_PREFIX "height", &val );
496 p_sys->i_height = val.i_int;
498 var_Get( p_stream, SOUT_CFG_PREFIX "maxwidth", &val );
499 p_sys->i_maxwidth = val.i_int;
501 var_Get( p_stream, SOUT_CFG_PREFIX "maxheight", &val );
502 p_sys->i_maxheight = val.i_int;
504 var_Get( p_stream, SOUT_CFG_PREFIX "vfilter", &val );
505 if( val.psz_string && *val.psz_string )
506 p_sys->psz_vf2 = val.psz_string;
509 free( val.psz_string );
510 p_sys->psz_vf2 = NULL;
513 var_Get( p_stream, SOUT_CFG_PREFIX "deinterlace", &val );
514 p_sys->b_deinterlace = val.b_bool;
516 var_Get( p_stream, SOUT_CFG_PREFIX "deinterlace-module", &val );
517 p_sys->psz_deinterlace = NULL;
518 p_sys->p_deinterlace_cfg = NULL;
519 if( val.psz_string && *val.psz_string )
522 psz_next = config_ChainCreate( &p_sys->psz_deinterlace,
523 &p_sys->p_deinterlace_cfg,
527 free( val.psz_string );
529 var_Get( p_stream, SOUT_CFG_PREFIX "threads", &val );
530 p_sys->i_threads = val.i_int;
531 var_Get( p_stream, SOUT_CFG_PREFIX "high-priority", &val );
532 p_sys->b_high_priority = val.b_bool;
534 if( p_sys->i_vcodec )
536 msg_Dbg( p_stream, "codec video=%4.4s %dx%d scaling: %f %dkb/s",
537 (char *)&p_sys->i_vcodec, p_sys->i_width, p_sys->i_height,
538 p_sys->f_scale, p_sys->i_vbitrate / 1000 );
541 /* Subpictures transcoding parameters */
543 p_sys->psz_senc = NULL;
544 p_sys->p_spu_cfg = NULL;
547 var_Get( p_stream, SOUT_CFG_PREFIX "senc", &val );
548 if( val.psz_string && *val.psz_string )
551 psz_next = config_ChainCreate( &p_sys->psz_senc, &p_sys->p_spu_cfg,
555 free( val.psz_string );
557 var_Get( p_stream, SOUT_CFG_PREFIX "scodec", &val );
558 if( val.psz_string && *val.psz_string )
561 memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) );
562 p_sys->i_scodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
564 free( val.psz_string );
566 if( p_sys->i_scodec )
568 msg_Dbg( p_stream, "codec spu=%4.4s", (char *)&p_sys->i_scodec );
571 var_Get( p_stream, SOUT_CFG_PREFIX "soverlay", &val );
572 p_sys->b_soverlay = val.b_bool;
574 var_Get( p_stream, SOUT_CFG_PREFIX "sfilter", &val );
575 if( val.psz_string && *val.psz_string )
577 p_sys->p_spu = spu_Create( p_stream );
578 var_Create( p_sys->p_spu, "sub-filter", VLC_VAR_STRING );
579 var_Set( p_sys->p_spu, "sub-filter", val );
580 spu_Init( p_sys->p_spu );
582 free( val.psz_string );
584 /* OSD menu transcoding parameters */
585 p_sys->psz_osdenc = NULL;
586 p_sys->p_osd_cfg = NULL;
587 p_sys->i_osdcodec = 0;
588 p_sys->b_osd = false;
590 var_Get( p_stream, SOUT_CFG_PREFIX "osd", &val );
596 psz_next = config_ChainCreate( &p_sys->psz_osdenc,
597 &p_sys->p_osd_cfg, strdup( "dvbsub") );
600 p_sys->i_osdcodec = VLC_FOURCC('Y','U','V','P' );
602 msg_Dbg( p_stream, "codec osd=%4.4s", (char *)&p_sys->i_osdcodec );
606 osd_val.psz_string = strdup("osdmenu");
607 p_sys->p_spu = spu_Create( p_stream );
608 var_Create( p_sys->p_spu, "sub-filter", VLC_VAR_STRING );
609 var_Set( p_sys->p_spu, "sub-filter", osd_val );
610 spu_Init( p_sys->p_spu );
611 free( osd_val.psz_string );
615 osd_val.psz_string = strdup("osdmenu");
616 var_Set( p_sys->p_spu, "sub-filter", osd_val );
617 free( osd_val.psz_string );
622 var_Get( p_stream, SOUT_CFG_PREFIX "audio-sync", &val );
623 p_sys->b_master_sync = val.b_bool;
624 if( p_sys->f_fps > 0 ) p_sys->b_master_sync = true;
626 p_stream->pf_add = Add;
627 p_stream->pf_del = Del;
628 p_stream->pf_send = Send;
629 p_stream->p_sys = p_sys;
634 /*****************************************************************************
636 *****************************************************************************/
637 static void Close( vlc_object_t * p_this )
639 sout_stream_t *p_stream = (sout_stream_t*)p_this;
640 sout_stream_sys_t *p_sys = p_stream->p_sys;
642 sout_StreamDelete( p_sys->p_out );
644 free( p_sys->psz_af2 );
646 while( p_sys->p_audio_cfg != NULL )
648 config_chain_t *p_next = p_sys->p_audio_cfg->p_next;
650 free( p_sys->p_audio_cfg->psz_name );
651 free( p_sys->p_audio_cfg->psz_value );
652 free( p_sys->p_audio_cfg );
654 p_sys->p_audio_cfg = p_next;
656 free( p_sys->psz_aenc );
658 free( p_sys->psz_vf2 );
660 while( p_sys->p_video_cfg != NULL )
662 config_chain_t *p_next = p_sys->p_video_cfg->p_next;
664 free( p_sys->p_video_cfg->psz_name );
665 free( p_sys->p_video_cfg->psz_value );
666 free( p_sys->p_video_cfg );
668 p_sys->p_video_cfg = p_next;
670 free( p_sys->psz_venc );
672 while( p_sys->p_deinterlace_cfg != NULL )
674 config_chain_t *p_next = p_sys->p_deinterlace_cfg->p_next;
676 free( p_sys->p_deinterlace_cfg->psz_name );
677 free( p_sys->p_deinterlace_cfg->psz_value );
678 free( p_sys->p_deinterlace_cfg );
680 p_sys->p_deinterlace_cfg = p_next;
682 free( p_sys->psz_deinterlace );
684 while( p_sys->p_spu_cfg != NULL )
686 config_chain_t *p_next = p_sys->p_spu_cfg->p_next;
688 free( p_sys->p_spu_cfg->psz_name );
689 free( p_sys->p_spu_cfg->psz_value );
690 free( p_sys->p_spu_cfg );
692 p_sys->p_spu_cfg = p_next;
694 free( p_sys->psz_senc );
696 if( p_sys->p_spu ) spu_Destroy( p_sys->p_spu );
698 while( p_sys->p_osd_cfg != NULL )
700 config_chain_t *p_next = p_sys->p_osd_cfg->p_next;
702 free( p_sys->p_osd_cfg->psz_name );
703 free( p_sys->p_osd_cfg->psz_value );
704 free( p_sys->p_osd_cfg );
706 p_sys->p_osd_cfg = p_next;
708 free( p_sys->psz_osdenc );
710 vlc_object_release( p_sys );
713 struct sout_stream_id_t
715 vlc_fourcc_t b_transcode;
717 /* id of the out stream */
721 decoder_t *p_decoder;
724 filter_chain_t *p_f_chain;
725 /* User specified filters */
726 filter_chain_t *p_uf_chain;
729 encoder_t *p_encoder;
732 date_t interpolated_pts;
735 static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
737 sout_stream_sys_t *p_sys = p_stream->p_sys;
738 sout_stream_id_t *id;
740 id = malloc( sizeof( sout_stream_id_t ) );
743 memset( id, 0, sizeof(sout_stream_id_t) );
746 id->p_decoder = NULL;
747 id->p_encoder = NULL;
749 /* Create decoder object */
750 id->p_decoder = vlc_object_create( p_stream, VLC_OBJECT_DECODER );
753 vlc_object_attach( id->p_decoder, p_stream );
754 id->p_decoder->p_module = NULL;
755 id->p_decoder->fmt_in = *p_fmt;
756 id->p_decoder->b_pace_control = true;
758 /* Create encoder object */
759 id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
762 vlc_object_attach( id->p_encoder, p_stream );
763 id->p_encoder->p_module = NULL;
765 /* Create destination format */
766 es_format_Init( &id->p_encoder->fmt_out, p_fmt->i_cat, 0 );
767 id->p_encoder->fmt_out.i_id = p_fmt->i_id;
768 id->p_encoder->fmt_out.i_group = p_fmt->i_group;
769 if( p_fmt->psz_language )
770 id->p_encoder->fmt_out.psz_language = strdup( p_fmt->psz_language );
772 if( p_fmt->i_cat == AUDIO_ES && (p_sys->i_acodec || p_sys->psz_aenc) )
775 "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
776 (char*)&p_fmt->i_codec, (char*)&p_sys->i_acodec );
778 /* Complete destination format */
779 id->p_encoder->fmt_out.i_codec = p_sys->i_acodec;
780 id->p_encoder->fmt_out.audio.i_rate = p_sys->i_sample_rate > 0 ?
781 p_sys->i_sample_rate : p_fmt->audio.i_rate;
782 id->p_encoder->fmt_out.i_bitrate = p_sys->i_abitrate;
783 id->p_encoder->fmt_out.audio.i_bitspersample =
784 p_fmt->audio.i_bitspersample;
785 id->p_encoder->fmt_out.audio.i_channels = p_sys->i_channels > 0 ?
786 p_sys->i_channels : p_fmt->audio.i_channels;
787 /* Sanity check for audio channels */
788 id->p_encoder->fmt_out.audio.i_channels =
789 __MIN( id->p_encoder->fmt_out.audio.i_channels,
790 id->p_decoder->fmt_in.audio.i_channels );
791 id->p_encoder->fmt_out.audio.i_original_channels =
792 id->p_decoder->fmt_in.audio.i_physical_channels;
793 if( id->p_decoder->fmt_in.audio.i_channels ==
794 id->p_encoder->fmt_out.audio.i_channels )
796 id->p_encoder->fmt_out.audio.i_physical_channels =
797 id->p_decoder->fmt_in.audio.i_physical_channels;
801 id->p_encoder->fmt_out.audio.i_physical_channels =
802 pi_channels_maps[id->p_encoder->fmt_out.audio.i_channels];
805 /* Build decoder -> filter -> encoder chain */
806 if( transcode_audio_new( p_stream, id ) )
808 msg_Err( p_stream, "cannot create audio chain" );
812 /* Open output stream */
813 id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_encoder->fmt_out );
814 id->b_transcode = true;
818 transcode_audio_close( id );
822 date_Init( &id->interpolated_pts, p_fmt->audio.i_rate, 1 );
824 else if( p_fmt->i_cat == VIDEO_ES &&
825 (p_sys->i_vcodec != 0 || p_sys->psz_venc) )
828 "creating video transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
829 (char*)&p_fmt->i_codec, (char*)&p_sys->i_vcodec );
831 /* Complete destination format */
832 id->p_encoder->fmt_out.i_codec = p_sys->i_vcodec;
833 id->p_encoder->fmt_out.video.i_width = p_sys->i_width & ~1;
834 id->p_encoder->fmt_out.video.i_height = p_sys->i_height & ~1;
835 id->p_encoder->fmt_out.i_bitrate = p_sys->i_vbitrate;
837 /* Build decoder -> filter -> encoder chain */
838 if( transcode_video_new( p_stream, id ) )
840 msg_Err( p_stream, "cannot create video chain" );
844 /* Stream will be added later on because we don't know
845 * all the characteristics of the decoded stream yet */
846 id->b_transcode = true;
848 if( p_sys->f_fps > 0 )
850 id->p_encoder->fmt_out.video.i_frame_rate =
851 (p_sys->f_fps * 1000) + 0.5;
852 id->p_encoder->fmt_out.video.i_frame_rate_base =
856 else if( ( p_fmt->i_cat == SPU_ES ) &&
857 ( p_sys->i_scodec || p_sys->psz_senc ) )
859 msg_Dbg( p_stream, "creating subtitles transcoding from fcc=`%4.4s' "
860 "to fcc=`%4.4s'", (char*)&p_fmt->i_codec,
861 (char*)&p_sys->i_scodec );
863 /* Complete destination format */
864 id->p_encoder->fmt_out.i_codec = p_sys->i_scodec;
866 /* build decoder -> filter -> encoder */
867 if( transcode_spu_new( p_stream, id ) )
869 msg_Err( p_stream, "cannot create subtitles chain" );
873 /* open output stream */
874 id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_encoder->fmt_out );
875 id->b_transcode = true;
879 transcode_spu_close( id );
883 else if( p_fmt->i_cat == SPU_ES && p_sys->b_soverlay )
885 msg_Dbg( p_stream, "subtitles (fcc=`%4.4s') overlaying",
886 (char*)&p_fmt->i_codec );
888 id->b_transcode = true;
890 /* Build decoder -> filter -> overlaying chain */
891 if( transcode_spu_new( p_stream, id ) )
893 msg_Err( p_stream, "cannot create subtitles chain" );
897 else if( !p_sys->b_osd && (p_sys->i_osdcodec != 0 || p_sys->psz_osdenc) )
899 msg_Dbg( p_stream, "creating osd transcoding from fcc=`%4.4s' "
900 "to fcc=`%4.4s'", (char*)&p_fmt->i_codec,
901 (char*)&p_sys->i_scodec );
903 id->b_transcode = true;
905 /* Create a fake OSD menu elementary stream */
906 if( transcode_osd_new( p_stream, id ) )
908 msg_Err( p_stream, "cannot create osd chain" );
915 msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
916 (char*)&p_fmt->i_codec );
917 id->id = sout_StreamIdAdd( p_sys->p_out, p_fmt );
918 id->b_transcode = false;
920 if( !id->id ) goto error;
930 vlc_object_detach( id->p_decoder );
931 vlc_object_release( id->p_decoder );
932 id->p_decoder = NULL;
937 vlc_object_detach( id->p_encoder );
938 es_format_Clean( &id->p_encoder->fmt_out );
939 vlc_object_release( id->p_encoder );
940 id->p_encoder = NULL;
948 static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
950 sout_stream_sys_t *p_sys = p_stream->p_sys;
952 if( id->b_transcode )
954 switch( id->p_decoder->fmt_in.i_cat )
957 transcode_audio_close( id );
960 transcode_video_close( p_stream, id );
964 transcode_osd_close( p_stream, id );
966 transcode_spu_close( id );
971 if( id->id ) sout_StreamIdDel( p_sys->p_out, id->id );
975 vlc_object_detach( id->p_decoder );
976 vlc_object_release( id->p_decoder );
977 id->p_decoder = NULL;
982 vlc_object_detach( id->p_encoder );
983 es_format_Clean( &id->p_encoder->fmt_out );
984 vlc_object_release( id->p_encoder );
985 id->p_encoder = NULL;
992 static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
995 sout_stream_sys_t *p_sys = p_stream->p_sys;
996 block_t *p_out = NULL;
998 if( !id->b_transcode && id->id )
1000 return sout_StreamIdSend( p_sys->p_out, id->id, p_buffer );
1002 else if( !id->b_transcode )
1004 block_Release( p_buffer );
1005 return VLC_EGENERIC;
1008 switch( id->p_decoder->fmt_in.i_cat )
1011 transcode_audio_process( p_stream, id, p_buffer, &p_out );
1015 if( transcode_video_process( p_stream, id, p_buffer, &p_out )
1018 return VLC_EGENERIC;
1023 /* Transcode OSD menu pictures. */
1026 if( transcode_osd_process( p_stream, id, p_buffer, &p_out ) !=
1029 return VLC_EGENERIC;
1032 else if ( transcode_spu_process( p_stream, id, p_buffer, &p_out ) !=
1035 return VLC_EGENERIC;
1041 block_Release( p_buffer );
1046 return sout_StreamIdSend( p_sys->p_out, id->id, p_out );
1050 /****************************************************************************
1052 ****************************************************************************/
1053 static inline void video_timer_start( encoder_t * p_encoder )
1055 stats_TimerStart( p_encoder, "encoding video frame",
1056 STATS_TIMER_VIDEO_FRAME_ENCODING );
1059 static inline void video_timer_stop( encoder_t * p_encoder )
1061 stats_TimerStop( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1064 static inline void video_timer_close( encoder_t * p_encoder )
1066 stats_TimerDump( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1067 stats_TimerClean( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1070 static inline void audio_timer_start( encoder_t * p_encoder )
1072 stats_TimerStart( p_encoder, "encoding audio frame",
1073 STATS_TIMER_AUDIO_FRAME_ENCODING );
1076 static inline void audio_timer_stop( encoder_t * p_encoder )
1078 stats_TimerStop( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1081 static inline void audio_timer_close( encoder_t * p_encoder )
1083 stats_TimerDump( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1084 stats_TimerClean( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1087 /****************************************************************************
1088 * decoder reencoder part
1089 ****************************************************************************/
1091 static block_t *transcode_audio_alloc( filter_t *p_filter, int size )
1093 VLC_UNUSED( p_filter );
1094 return block_Alloc( size );
1097 static int transcode_audio_filter_allocation_init( filter_t *p_filter,
1101 p_filter->pf_audio_buffer_new = transcode_audio_alloc;
1105 static int transcode_audio_new( sout_stream_t *p_stream,
1106 sout_stream_id_t *id )
1108 sout_stream_sys_t *p_sys = p_stream->p_sys;
1109 es_format_t fmt_last;
1116 /* Initialization of decoder structures */
1117 id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1118 id->p_decoder->fmt_out.i_extra = 0;
1119 id->p_decoder->fmt_out.p_extra = 0;
1120 id->p_decoder->pf_decode_audio = NULL;
1121 id->p_decoder->pf_aout_buffer_new = audio_new_buffer;
1122 id->p_decoder->pf_aout_buffer_del = audio_del_buffer;
1123 /* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */
1125 id->p_decoder->p_module =
1126 module_need( id->p_decoder, "decoder", "$codec", 0 );
1127 if( !id->p_decoder->p_module )
1129 msg_Err( p_stream, "cannot find audio decoder" );
1130 return VLC_EGENERIC;
1132 id->p_decoder->fmt_out.audio.i_bitspersample =
1133 aout_BitsPerSample( id->p_decoder->fmt_out.i_codec );
1134 fmt_last = id->p_decoder->fmt_out;
1135 /* Fix AAC SBR changing number of channels and sampling rate */
1136 if( !(id->p_decoder->fmt_in.i_codec == VLC_FOURCC('m','p','4','a') &&
1137 fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate &&
1138 fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels) )
1139 fmt_last.audio.i_rate = id->p_decoder->fmt_in.audio.i_rate;
1145 /* Initialization of encoder format structures */
1146 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1147 id->p_decoder->fmt_out.i_codec );
1148 id->p_encoder->fmt_in.audio.i_format = id->p_decoder->fmt_out.i_codec;
1150 id->p_encoder->fmt_in.audio.i_rate = id->p_encoder->fmt_out.audio.i_rate;
1151 id->p_encoder->fmt_in.audio.i_physical_channels =
1152 id->p_encoder->fmt_out.audio.i_physical_channels;
1153 id->p_encoder->fmt_in.audio.i_original_channels =
1154 id->p_encoder->fmt_out.audio.i_original_channels;
1155 id->p_encoder->fmt_in.audio.i_channels =
1156 id->p_encoder->fmt_out.audio.i_channels;
1157 id->p_encoder->fmt_in.audio.i_bitspersample =
1158 aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1160 id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1161 id->p_encoder->p_module =
1162 module_need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1163 if( !id->p_encoder->p_module )
1165 msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)",
1166 p_sys->psz_aenc ? p_sys->psz_aenc : "any",
1167 (char *)&p_sys->i_acodec );
1168 module_unneed( id->p_decoder, id->p_decoder->p_module );
1169 id->p_decoder->p_module = NULL;
1170 return VLC_EGENERIC;
1172 id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1173 id->p_encoder->fmt_in.audio.i_bitspersample =
1174 aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1176 /* Init filter chain */
1177 id->p_f_chain = filter_chain_New( p_stream, "audio filter2", true,
1178 transcode_audio_filter_allocation_init, NULL, NULL );
1179 filter_chain_Reset( id->p_f_chain, &fmt_last, &id->p_encoder->fmt_in );
1181 /* Load conversion filters */
1182 if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels ||
1183 fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1185 /* We'll have to go through fl32 first */
1186 fmt_last.i_codec = fmt_last.audio.i_format = VLC_FOURCC('f','l','3','2');
1187 fmt_last.audio.i_bitspersample = aout_BitsPerSample( fmt_last.i_codec );
1188 filter_chain_AppendFilter( id->p_f_chain, NULL, NULL, NULL, &fmt_last );
1189 fmt_last = *filter_chain_GetFmtOut( id->p_f_chain );
1192 for( i = 0; i < 4; i++ )
1194 if( (fmt_last.audio.i_channels !=
1195 id->p_encoder->fmt_in.audio.i_channels) ||
1196 (fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate) ||
1197 (fmt_last.i_codec != id->p_encoder->fmt_in.i_codec) )
1199 msg_Dbg( p_stream, "Looking for filter "
1200 "(%4.4s->%4.4s, channels %d->%d, rate %d->%d)",
1201 (char *)&fmt_last.i_codec,
1202 (char *)&id->p_encoder->fmt_in.i_codec,
1203 fmt_last.audio.i_channels,
1204 id->p_encoder->fmt_in.audio.i_channels,
1205 fmt_last.audio.i_rate,
1206 id->p_encoder->fmt_in.audio.i_rate );
1207 filter_chain_AppendFilter( id->p_f_chain, NULL, NULL,
1208 &fmt_last, &id->p_encoder->fmt_in );
1209 fmt_last = *filter_chain_GetFmtOut( id->p_f_chain );
1214 /* Final checks to see if conversions were successful */
1215 if( fmt_last.i_codec != id->p_encoder->fmt_in.i_codec )
1217 msg_Err( p_stream, "no audio filter found "
1218 "(%4.4s->%4.4s, channels %d->%d, rate %d->%d)",
1219 (char *)&fmt_last.i_codec,
1220 (char *)&id->p_encoder->fmt_in.i_codec,
1221 fmt_last.audio.i_channels,
1222 id->p_encoder->fmt_in.audio.i_channels,
1223 fmt_last.audio.i_rate,
1224 id->p_encoder->fmt_in.audio.i_rate );
1225 transcode_audio_close( id );
1226 return VLC_EGENERIC;
1229 /* Load user specified audio filters now */
1230 if( p_sys->psz_af2 )
1232 id->p_uf_chain = filter_chain_New( p_stream, "audio filter2", false,
1233 transcode_audio_filter_allocation_init, NULL, NULL );
1234 filter_chain_Reset( id->p_uf_chain, &fmt_last, &id->p_encoder->fmt_in );
1235 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_af2 );
1236 fmt_last = *filter_chain_GetFmtOut( id->p_uf_chain );
1239 if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels )
1242 module_unneed( id->p_encoder, id->p_encoder->p_module );
1243 id->p_encoder->p_module = NULL;
1245 /* This might work, but only if the encoder is restarted */
1246 id->p_encoder->fmt_in.audio.i_channels = fmt_last.audio.i_channels;
1247 id->p_encoder->fmt_out.audio.i_channels = fmt_last.audio.i_channels;
1249 id->p_encoder->fmt_in.audio.i_physical_channels =
1250 id->p_encoder->fmt_in.audio.i_original_channels =
1251 fmt_last.audio.i_physical_channels;
1252 id->p_encoder->fmt_out.audio.i_physical_channels =
1253 id->p_encoder->fmt_out.audio.i_original_channels =
1254 fmt_last.audio.i_physical_channels;
1256 msg_Dbg( p_stream, "number of audio channels for mixing changed, "
1257 "trying to reopen the encoder for mixing %i to %i channels",
1258 fmt_last.audio.i_channels,
1259 id->p_encoder->fmt_in.audio.i_channels );
1261 /* reload encoder */
1262 id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1263 id->p_encoder->p_module =
1264 module_need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1265 if( !id->p_encoder->p_module ||
1266 fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels ||
1267 fmt_last.i_codec != id->p_encoder->fmt_in.i_codec )
1269 if( id->p_encoder->p_module )
1271 module_unneed( id->p_encoder, id->p_encoder->p_module );
1272 id->p_encoder->p_module = NULL;
1274 msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)",
1275 p_sys->psz_aenc ? p_sys->psz_aenc : "any",
1276 (char *)&p_sys->i_acodec );
1277 transcode_audio_close( id );
1278 return VLC_EGENERIC;
1280 id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1281 id->p_encoder->fmt_in.audio.i_bitspersample =
1282 aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1284 msg_Err( p_stream, "no audio filter found for mixing from"
1285 " %i to %i channels", fmt_last.audio.i_channels,
1286 id->p_encoder->fmt_in.audio.i_channels );
1288 transcode_audio_close( id );
1289 return VLC_EGENERIC;
1293 if( fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1295 msg_Err( p_stream, "no audio filter found for resampling from"
1296 " %iHz to %iHz", fmt_last.audio.i_rate,
1297 id->p_encoder->fmt_in.audio.i_rate );
1299 /* FIXME : this might work, but only if the encoder is restarted */
1300 id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;
1301 id->p_encoder->fmt_out.audio.i_rate = fmt_last.audio.i_rate;
1303 transcode_audio_close( id );
1304 return VLC_EGENERIC;
1308 /* FIXME: Hack for mp3 transcoding support */
1309 if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC( 'm','p','3',' ' ) )
1310 id->p_encoder->fmt_out.i_codec = VLC_FOURCC( 'm','p','g','a' );
1315 static void transcode_audio_close( sout_stream_id_t *id )
1317 audio_timer_close( id->p_encoder );
1320 if( id->p_decoder->p_module )
1321 module_unneed( id->p_decoder, id->p_decoder->p_module );
1322 id->p_decoder->p_module = NULL;
1325 if( id->p_encoder->p_module )
1326 module_unneed( id->p_encoder, id->p_encoder->p_module );
1327 id->p_encoder->p_module = NULL;
1331 filter_chain_Delete( id->p_f_chain );
1332 if( id->p_uf_chain )
1333 filter_chain_Delete( id->p_uf_chain );
1336 static int transcode_audio_process( sout_stream_t *p_stream,
1337 sout_stream_id_t *id,
1338 block_t *in, block_t **out )
1340 sout_stream_sys_t *p_sys = p_stream->p_sys;
1341 aout_buffer_t *p_audio_buf;
1342 block_t *p_block, *p_audio_block;
1345 while( (p_audio_buf = id->p_decoder->pf_decode_audio( id->p_decoder,
1348 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_AUDIO, 1 );
1349 if( p_sys->b_master_sync )
1351 mtime_t i_dts = date_Get( &id->interpolated_pts ) + 1;
1352 if ( p_audio_buf->start_date - i_dts > MASTER_SYNC_MAX_DRIFT
1353 || p_audio_buf->start_date - i_dts < -MASTER_SYNC_MAX_DRIFT )
1355 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1356 date_Set( &id->interpolated_pts, p_audio_buf->start_date );
1357 i_dts = p_audio_buf->start_date + 1;
1359 p_sys->i_master_drift = p_audio_buf->start_date - i_dts;
1360 date_Increment( &id->interpolated_pts, p_audio_buf->i_nb_samples );
1361 p_audio_buf->start_date -= p_sys->i_master_drift;
1362 p_audio_buf->end_date -= p_sys->i_master_drift;
1365 p_audio_block = p_audio_buf->p_sys;
1366 p_audio_block->i_buffer = p_audio_buf->i_nb_bytes;
1367 p_audio_block->i_dts = p_audio_block->i_pts =
1368 p_audio_buf->start_date;
1369 p_audio_block->i_length = p_audio_buf->end_date -
1370 p_audio_buf->start_date;
1371 p_audio_block->i_samples = p_audio_buf->i_nb_samples;
1373 /* Run filter chain */
1374 p_audio_block = filter_chain_AudioFilter( id->p_f_chain, p_audio_block );
1375 if( id->p_uf_chain )
1376 p_audio_block = filter_chain_AudioFilter( id->p_uf_chain, p_audio_block );
1377 assert( p_audio_block );
1379 p_audio_buf->p_buffer = p_audio_block->p_buffer;
1380 p_audio_buf->i_nb_bytes = p_audio_block->i_buffer;
1381 p_audio_buf->i_nb_samples = p_audio_block->i_samples;
1382 p_audio_buf->start_date = p_audio_block->i_dts;
1383 p_audio_buf->end_date = p_audio_block->i_dts + p_audio_block->i_length;
1385 audio_timer_start( id->p_encoder );
1386 p_block = id->p_encoder->pf_encode_audio( id->p_encoder, p_audio_buf );
1387 audio_timer_stop( id->p_encoder );
1389 block_ChainAppend( out, p_block );
1390 block_Release( p_audio_block );
1391 free( p_audio_buf );
1397 static void audio_release_buffer( aout_buffer_t *p_buffer )
1399 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1403 static aout_buffer_t *audio_new_buffer( decoder_t *p_dec, int i_samples )
1405 aout_buffer_t *p_buffer;
1409 if( p_dec->fmt_out.audio.i_bitspersample )
1411 i_size = i_samples * p_dec->fmt_out.audio.i_bitspersample / 8 *
1412 p_dec->fmt_out.audio.i_channels;
1414 else if( p_dec->fmt_out.audio.i_bytes_per_frame &&
1415 p_dec->fmt_out.audio.i_frame_length )
1417 i_size = i_samples * p_dec->fmt_out.audio.i_bytes_per_frame /
1418 p_dec->fmt_out.audio.i_frame_length;
1422 i_size = i_samples * 4 * p_dec->fmt_out.audio.i_channels;
1425 p_buffer = malloc( sizeof(aout_buffer_t) );
1426 if( !p_buffer ) return NULL;
1427 p_buffer->b_discontinuity = false;
1428 p_buffer->pf_release = audio_release_buffer;
1429 p_buffer->p_sys = p_block = block_New( p_dec, i_size );
1431 p_buffer->p_buffer = p_block->p_buffer;
1432 p_buffer->i_size = p_buffer->i_nb_bytes = p_block->i_buffer;
1433 p_buffer->i_nb_samples = i_samples;
1434 p_block->i_samples = i_samples;
1439 static void audio_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
1442 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1450 static int transcode_video_filter_allocation_init( filter_t *p_filter,
1453 sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_data;
1456 p_filter->pf_vout_buffer_new = video_new_buffer_filter;
1457 p_filter->pf_vout_buffer_del = video_del_buffer_filter;
1459 p_filter->p_owner = malloc( sizeof(filter_owner_sys_t) );
1460 if( !p_filter->p_owner )
1461 return VLC_EGENERIC;
1463 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1464 p_filter->p_owner->pp_pics[i] = 0;
1465 p_filter->p_owner->p_sys = p_sys;
1470 static void transcode_video_filter_allocation_clear( filter_t *p_filter )
1474 /* Clean-up pictures ring buffer */
1475 for( j = 0; j < PICTURE_RING_SIZE; j++ )
1477 if( p_filter->p_owner->pp_pics[j] )
1478 video_del_buffer( VLC_OBJECT(p_filter),
1479 p_filter->p_owner->pp_pics[j] );
1481 free( p_filter->p_owner );
1484 static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
1486 sout_stream_sys_t *p_sys = p_stream->p_sys;
1490 * Initialization of decoder structures
1492 id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1493 id->p_decoder->fmt_out.i_extra = 0;
1494 id->p_decoder->fmt_out.p_extra = 0;
1495 id->p_decoder->pf_decode_video = NULL;
1496 id->p_decoder->pf_get_cc = NULL;
1497 id->p_decoder->pf_get_cc = 0;
1498 id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
1499 id->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder;
1500 id->p_decoder->pf_picture_link = video_link_picture_decoder;
1501 id->p_decoder->pf_picture_unlink = video_unlink_picture_decoder;
1502 id->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) );
1503 if( !id->p_decoder->p_owner )
1504 return VLC_EGENERIC;
1506 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1507 id->p_decoder->p_owner->pp_pics[i] = 0;
1508 id->p_decoder->p_owner->p_sys = p_sys;
1509 /* id->p_decoder->p_cfg = p_sys->p_video_cfg; */
1511 id->p_decoder->p_module =
1512 module_need( id->p_decoder, "decoder", "$codec", 0 );
1514 if( !id->p_decoder->p_module )
1516 msg_Err( p_stream, "cannot find video decoder" );
1517 free( id->p_decoder->p_owner );
1518 return VLC_EGENERIC;
1523 * Because some info about the decoded input will only be available
1524 * once the first frame is decoded, we actually only test the availability
1525 * of the encoder here.
1528 /* Initialization of encoder format structures */
1529 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1530 id->p_decoder->fmt_out.i_codec );
1531 id->p_encoder->fmt_in.video.i_chroma = id->p_decoder->fmt_out.i_codec;
1533 /* The dimensions will be set properly later on.
1534 * Just put sensible values so we can test an encoder is available. */
1535 id->p_encoder->fmt_in.video.i_width =
1536 id->p_encoder->fmt_out.video.i_width ?:
1537 id->p_decoder->fmt_in.video.i_width ?: 16;
1538 id->p_encoder->fmt_in.video.i_height =
1539 id->p_encoder->fmt_out.video.i_height ?:
1540 id->p_decoder->fmt_in.video.i_height ?: 16;
1541 id->p_encoder->fmt_in.video.i_frame_rate = ENC_FRAMERATE;
1542 id->p_encoder->fmt_in.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1544 id->p_encoder->i_threads = p_sys->i_threads;
1545 id->p_encoder->p_cfg = p_sys->p_video_cfg;
1547 id->p_encoder->p_module =
1548 module_need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1549 if( !id->p_encoder->p_module )
1551 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1552 p_sys->psz_venc ? p_sys->psz_venc : "any",
1553 (char *)&p_sys->i_vcodec );
1554 module_unneed( id->p_decoder, id->p_decoder->p_module );
1555 id->p_decoder->p_module = 0;
1556 free( id->p_decoder->p_owner );
1557 return VLC_EGENERIC;
1560 /* Close the encoder.
1561 * We'll open it only when we have the first frame. */
1562 module_unneed( id->p_encoder, id->p_encoder->p_module );
1563 if( id->p_encoder->fmt_out.p_extra )
1565 free( id->p_encoder->fmt_out.p_extra );
1566 id->p_encoder->fmt_out.p_extra = NULL;
1567 id->p_encoder->fmt_out.i_extra = 0;
1569 id->p_encoder->p_module = NULL;
1571 if( p_sys->i_threads >= 1 )
1573 int i_priority = p_sys->b_high_priority ? VLC_THREAD_PRIORITY_OUTPUT :
1574 VLC_THREAD_PRIORITY_VIDEO;
1575 p_sys->id_video = id;
1576 vlc_mutex_init( &p_sys->lock_out );
1577 vlc_cond_init( &p_sys->cond );
1578 memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) );
1579 p_sys->i_first_pic = 0;
1580 p_sys->i_last_pic = 0;
1581 p_sys->p_buffers = NULL;
1582 p_sys->b_die = p_sys->b_error = 0;
1583 if( vlc_thread_create( p_sys, "encoder", EncoderThread, i_priority,
1586 msg_Err( p_stream, "cannot spawn encoder thread" );
1587 module_unneed( id->p_decoder, id->p_decoder->p_module );
1588 id->p_decoder->p_module = 0;
1589 free( id->p_decoder->p_owner );
1590 return VLC_EGENERIC;
1597 static void transcode_video_encoder_init( sout_stream_t *p_stream,
1598 sout_stream_id_t *id )
1600 sout_stream_sys_t *p_sys = p_stream->p_sys;
1602 /* Calculate scaling
1603 * width/height of source */
1604 int i_src_width = id->p_decoder->fmt_out.video.i_width;
1605 int i_src_height = id->p_decoder->fmt_out.video.i_height;
1607 /* with/height scaling */
1608 float f_scale_width = 1;
1609 float f_scale_height = 1;
1611 /* width/height of output stream */
1616 float f_aspect = (float)id->p_decoder->fmt_out.video.i_aspect /
1619 msg_Dbg( p_stream, "decoder aspect is %i:%i",
1620 id->p_decoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1622 /* Change f_aspect from source frame to source pixel */
1623 f_aspect = f_aspect * i_src_height / i_src_width;
1624 msg_Dbg( p_stream, "source pixel aspect is %f:1", f_aspect );
1626 /* Calculate scaling factor for specified parameters */
1627 if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1628 id->p_encoder->fmt_out.video.i_height <= 0 && p_sys->f_scale )
1630 /* Global scaling. Make sure width will remain a factor of 16 */
1633 int i_new_width = i_src_width * p_sys->f_scale;
1635 if( i_new_width % 16 <= 7 && i_new_width >= 16 )
1636 i_new_width -= i_new_width % 16;
1638 i_new_width += 16 - i_new_width % 16;
1640 f_real_scale = (float)( i_new_width ) / (float) i_src_width;
1642 i_new_height = __MAX( 16, i_src_height * (float)f_real_scale );
1644 f_scale_width = f_real_scale;
1645 f_scale_height = (float) i_new_height / (float) i_src_height;
1647 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1648 id->p_encoder->fmt_out.video.i_height <= 0 )
1650 /* Only width specified */
1651 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1652 f_scale_height = f_scale_width;
1654 else if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1655 id->p_encoder->fmt_out.video.i_height > 0 )
1657 /* Only height specified */
1658 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1659 f_scale_width = f_scale_height;
1661 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1662 id->p_encoder->fmt_out.video.i_height > 0 )
1664 /* Width and height specified */
1665 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1666 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1669 /* check maxwidth and maxheight
1671 if( p_sys->i_maxwidth && f_scale_width > (float)p_sys->i_maxwidth /
1674 f_scale_width = (float)p_sys->i_maxwidth / i_src_width;
1677 if( p_sys->i_maxheight && f_scale_height > (float)p_sys->i_maxheight /
1680 f_scale_height = (float)p_sys->i_maxheight / i_src_height;
1684 /* Change aspect ratio from source pixel to scaled pixel */
1685 f_aspect = f_aspect * f_scale_height / f_scale_width;
1686 msg_Dbg( p_stream, "scaled pixel aspect is %f:1", f_aspect );
1688 /* f_scale_width and f_scale_height are now final */
1689 /* Calculate width, height from scaling
1690 * Make sure its multiple of 2
1692 i_dst_width = 2 * (int)(f_scale_width*i_src_width/2+0.5);
1693 i_dst_height = 2 * (int)(f_scale_height*i_src_height/2+0.5);
1695 /* Change aspect ratio from scaled pixel to output frame */
1696 f_aspect = f_aspect * i_dst_width / i_dst_height;
1698 /* Store calculated values */
1699 id->p_encoder->fmt_out.video.i_width =
1700 id->p_encoder->fmt_out.video.i_visible_width = i_dst_width;
1701 id->p_encoder->fmt_out.video.i_height =
1702 id->p_encoder->fmt_out.video.i_visible_height = i_dst_height;
1704 id->p_encoder->fmt_in.video.i_width =
1705 id->p_encoder->fmt_in.video.i_visible_width = i_dst_width;
1706 id->p_encoder->fmt_in.video.i_height =
1707 id->p_encoder->fmt_in.video.i_visible_height = i_dst_height;
1709 msg_Dbg( p_stream, "source %ix%i, destination %ix%i",
1710 i_src_width, i_src_height,
1711 i_dst_width, i_dst_height
1714 /* Handle frame rate conversion */
1715 if( !id->p_encoder->fmt_out.video.i_frame_rate ||
1716 !id->p_encoder->fmt_out.video.i_frame_rate_base )
1718 if( id->p_decoder->fmt_out.video.i_frame_rate &&
1719 id->p_decoder->fmt_out.video.i_frame_rate_base )
1721 id->p_encoder->fmt_out.video.i_frame_rate =
1722 id->p_decoder->fmt_out.video.i_frame_rate;
1723 id->p_encoder->fmt_out.video.i_frame_rate_base =
1724 id->p_decoder->fmt_out.video.i_frame_rate_base;
1728 /* Pick a sensible default value */
1729 id->p_encoder->fmt_out.video.i_frame_rate = ENC_FRAMERATE;
1730 id->p_encoder->fmt_out.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1734 id->p_encoder->fmt_in.video.i_frame_rate =
1735 id->p_encoder->fmt_out.video.i_frame_rate;
1736 id->p_encoder->fmt_in.video.i_frame_rate_base =
1737 id->p_encoder->fmt_out.video.i_frame_rate_base;
1739 date_Init( &id->interpolated_pts,
1740 id->p_encoder->fmt_out.video.i_frame_rate,
1741 id->p_encoder->fmt_out.video.i_frame_rate_base );
1743 /* Check whether a particular aspect ratio was requested */
1744 if( !id->p_encoder->fmt_out.video.i_aspect )
1746 id->p_encoder->fmt_out.video.i_aspect =
1747 (int)( f_aspect * VOUT_ASPECT_FACTOR + 0.5 );
1749 id->p_encoder->fmt_in.video.i_aspect =
1750 id->p_encoder->fmt_out.video.i_aspect;
1752 msg_Dbg( p_stream, "encoder aspect is %i:%i",
1753 id->p_encoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1755 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1758 static int transcode_video_encoder_open( sout_stream_t *p_stream,
1759 sout_stream_id_t *id )
1761 sout_stream_sys_t *p_sys = p_stream->p_sys;
1764 msg_Dbg( p_stream, "destination (after video filters) %ix%i",
1765 id->p_encoder->fmt_in.video.i_width,
1766 id->p_encoder->fmt_in.video.i_height );
1768 id->p_encoder->p_module =
1769 module_need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1770 if( !id->p_encoder->p_module )
1772 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1773 p_sys->psz_venc ? p_sys->psz_venc : "any",
1774 (char *)&p_sys->i_vcodec );
1775 return VLC_EGENERIC;
1778 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1780 /* Hack for mp2v/mp1v transcoding support */
1781 if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','1','v') ||
1782 id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','2','v') )
1784 id->p_encoder->fmt_out.i_codec = VLC_FOURCC('m','p','g','v');
1787 id->id = sout_StreamIdAdd( p_stream->p_sys->p_out,
1788 &id->p_encoder->fmt_out );
1791 msg_Err( p_stream, "cannot add this stream" );
1792 return VLC_EGENERIC;
1798 static void transcode_video_close( sout_stream_t *p_stream,
1799 sout_stream_id_t *id )
1803 if( p_stream->p_sys->i_threads >= 1 )
1805 vlc_mutex_lock( &p_stream->p_sys->lock_out );
1806 vlc_object_kill( p_stream->p_sys );
1807 vlc_cond_signal( &p_stream->p_sys->cond );
1808 vlc_mutex_unlock( &p_stream->p_sys->lock_out );
1809 vlc_thread_join( p_stream->p_sys );
1810 vlc_mutex_destroy( &p_stream->p_sys->lock_out );
1811 vlc_cond_destroy( &p_stream->p_sys->cond );
1814 video_timer_close( id->p_encoder );
1817 if( id->p_decoder->p_module )
1818 module_unneed( id->p_decoder, id->p_decoder->p_module );
1820 if( id->p_decoder->p_owner )
1822 /* Clean-up pictures ring buffer */
1823 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1825 if( id->p_decoder->p_owner->pp_pics[i] )
1826 video_del_buffer( VLC_OBJECT(id->p_decoder),
1827 id->p_decoder->p_owner->pp_pics[i] );
1829 free( id->p_decoder->p_owner );
1833 if( id->p_encoder->p_module )
1834 module_unneed( id->p_encoder, id->p_encoder->p_module );
1838 filter_chain_Delete( id->p_f_chain );
1839 if( id->p_uf_chain )
1840 filter_chain_Delete( id->p_uf_chain );
1843 static int transcode_video_process( sout_stream_t *p_stream,
1844 sout_stream_id_t *id,
1845 block_t *in, block_t **out )
1847 sout_stream_sys_t *p_sys = p_stream->p_sys;
1848 int i_duplicate = 1;
1849 picture_t *p_pic, *p_pic2 = NULL;
1852 while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
1854 subpicture_t *p_subpic = NULL;
1856 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_VIDEO, 1 );
1858 if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )
1860 mtime_t current_date = mdate();
1861 if( current_date + 50000 > p_pic->date )
1863 msg_Dbg( p_stream, "late picture skipped (%"PRId64")",
1864 current_date + 50000 - p_pic->date );
1865 p_pic->pf_release( p_pic );
1870 if( p_sys->b_master_sync )
1872 mtime_t i_video_drift;
1873 mtime_t i_master_drift = p_sys->i_master_drift;
1876 i_pts = date_Get( &id->interpolated_pts ) + 1;
1877 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1878 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
1880 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1881 date_Set( &id->interpolated_pts, p_pic->date );
1882 i_pts = p_pic->date + 1;
1884 i_video_drift = p_pic->date - i_pts;
1887 /* Set the pts of the frame being encoded */
1888 p_pic->date = i_pts;
1890 if( i_video_drift < (i_master_drift - 50000) )
1893 msg_Dbg( p_stream, "dropping frame (%i)",
1894 (int)(i_video_drift - i_master_drift) );
1896 p_pic->pf_release( p_pic );
1899 else if( i_video_drift > (i_master_drift + 50000) )
1902 msg_Dbg( p_stream, "adding frame (%i)",
1903 (int)(i_video_drift - i_master_drift) );
1909 if( !id->p_encoder->p_module )
1911 transcode_video_encoder_init( p_stream, id );
1913 id->p_f_chain = filter_chain_New( p_stream, "video filter2",
1915 transcode_video_filter_allocation_init,
1916 transcode_video_filter_allocation_clear,
1920 if( p_stream->p_sys->b_deinterlace )
1922 filter_chain_AppendFilter( id->p_f_chain,
1923 p_sys->psz_deinterlace,
1924 p_sys->p_deinterlace_cfg,
1925 &id->p_decoder->fmt_out,
1926 &id->p_decoder->fmt_out );
1929 /* Take care of the scaling and chroma conversions */
1930 if( ( id->p_decoder->fmt_out.video.i_chroma !=
1931 id->p_encoder->fmt_in.video.i_chroma ) ||
1932 ( id->p_decoder->fmt_out.video.i_width !=
1933 id->p_encoder->fmt_in.video.i_width ) ||
1934 ( id->p_decoder->fmt_out.video.i_height !=
1935 id->p_encoder->fmt_in.video.i_height ) )
1937 filter_chain_AppendFilter( id->p_f_chain,
1939 &id->p_decoder->fmt_out,
1940 &id->p_encoder->fmt_in );
1943 if( p_sys->psz_vf2 )
1945 const es_format_t *p_fmt_out;
1946 id->p_uf_chain = filter_chain_New( p_stream, "video filter2",
1948 transcode_video_filter_allocation_init,
1949 transcode_video_filter_allocation_clear,
1951 filter_chain_Reset( id->p_uf_chain, &id->p_encoder->fmt_in,
1952 &id->p_encoder->fmt_in );
1953 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_vf2 );
1954 p_fmt_out = filter_chain_GetFmtOut( id->p_uf_chain );
1955 es_format_Copy( &id->p_encoder->fmt_in, p_fmt_out );
1956 id->p_encoder->fmt_out.video.i_width =
1957 id->p_encoder->fmt_in.video.i_width;
1958 id->p_encoder->fmt_out.video.i_height =
1959 id->p_encoder->fmt_in.video.i_height;
1960 id->p_encoder->fmt_out.video.i_aspect =
1961 id->p_encoder->fmt_in.video.i_aspect;
1964 if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS )
1966 p_pic->pf_release( p_pic );
1967 transcode_video_close( p_stream, id );
1968 id->b_transcode = false;
1969 return VLC_EGENERIC;
1973 /* Run filter chain */
1975 p_pic = filter_chain_VideoFilter( id->p_f_chain, p_pic );
1981 /* Check if we have a subpicture to overlay */
1984 p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date,
1985 false /* Fixme: check if stream is paused */, false );
1986 /* TODO: get another pic */
1989 /* Overlay subpicture */
1994 if( p_pic->i_refcount && !filter_chain_GetLength( id->p_f_chain ) )
1996 /* We can't modify the picture, we need to duplicate it */
1997 picture_t *p_tmp = video_new_buffer_decoder( id->p_decoder );
2000 picture_Copy( p_tmp, p_pic );
2001 p_pic->pf_release( p_pic );
2006 if( filter_chain_GetLength( id->p_f_chain ) > 0 )
2007 fmt = filter_chain_GetFmtOut( id->p_f_chain )->video;
2009 fmt = id->p_decoder->fmt_out.video;
2011 /* FIXME (shouldn't have to be done here) */
2012 fmt.i_sar_num = fmt.i_aspect * fmt.i_height / fmt.i_width;
2013 fmt.i_sar_den = VOUT_ASPECT_FACTOR;
2015 spu_RenderSubpictures( p_sys->p_spu, p_pic, &fmt,
2016 p_subpic, &id->p_decoder->fmt_out.video, false );
2019 /* Run user specified filter chain */
2020 if( id->p_uf_chain )
2021 p_pic = filter_chain_VideoFilter( id->p_uf_chain, p_pic );
2023 if( p_sys->i_threads == 0 )
2027 video_timer_start( id->p_encoder );
2028 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2029 video_timer_stop( id->p_encoder );
2031 block_ChainAppend( out, p_block );
2034 if( p_sys->b_master_sync )
2036 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
2037 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
2038 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
2040 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2041 date_Set( &id->interpolated_pts, p_pic->date );
2042 i_pts = p_pic->date + 1;
2044 date_Increment( &id->interpolated_pts, 1 );
2047 if( p_sys->b_master_sync && i_duplicate > 1 )
2049 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
2050 if( (p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT)
2051 || ((p_pic->date - i_pts) < -MASTER_SYNC_MAX_DRIFT) )
2053 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2054 date_Set( &id->interpolated_pts, p_pic->date );
2055 i_pts = p_pic->date + 1;
2057 date_Increment( &id->interpolated_pts, 1 );
2059 if( p_sys->i_threads >= 1 )
2061 /* We can't modify the picture, we need to duplicate it */
2062 p_pic2 = video_new_buffer_decoder( id->p_decoder );
2063 if( p_pic2 != NULL )
2065 picture_Copy( p_pic2, p_pic );
2066 p_pic2->date = i_pts;
2072 p_pic->date = i_pts;
2073 video_timer_start( id->p_encoder );
2074 p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);
2075 video_timer_stop( id->p_encoder );
2076 block_ChainAppend( out, p_block );
2080 if( p_sys->i_threads == 0 )
2082 p_pic->pf_release( p_pic );
2086 vlc_mutex_lock( &p_sys->lock_out );
2087 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
2088 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2089 *out = p_sys->p_buffers;
2090 p_sys->p_buffers = NULL;
2091 if( p_pic2 != NULL )
2093 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic2;
2094 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2096 vlc_cond_signal( &p_sys->cond );
2097 vlc_mutex_unlock( &p_sys->lock_out );
2104 static void* EncoderThread( vlc_object_t* p_this )
2106 sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_this;
2107 sout_stream_id_t *id = p_sys->id_video;
2109 int canc = vlc_savecancel ();
2111 while( vlc_object_alive (p_sys) && !p_sys->b_error )
2115 vlc_mutex_lock( &p_sys->lock_out );
2116 while( p_sys->i_last_pic == p_sys->i_first_pic )
2118 vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );
2119 if( !vlc_object_alive (p_sys) || p_sys->b_error ) break;
2121 if( !vlc_object_alive (p_sys) || p_sys->b_error )
2123 vlc_mutex_unlock( &p_sys->lock_out );
2127 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2128 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2129 vlc_mutex_unlock( &p_sys->lock_out );
2131 video_timer_start( id->p_encoder );
2132 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2133 video_timer_stop( id->p_encoder );
2135 vlc_mutex_lock( &p_sys->lock_out );
2136 block_ChainAppend( &p_sys->p_buffers, p_block );
2138 vlc_mutex_unlock( &p_sys->lock_out );
2139 p_pic->pf_release( p_pic );
2142 while( p_sys->i_last_pic != p_sys->i_first_pic )
2144 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2145 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2146 p_pic->pf_release( p_pic );
2148 block_ChainRelease( p_sys->p_buffers );
2150 vlc_restorecancel (canc);
2154 struct picture_sys_t
2156 vlc_object_t *p_owner;
2159 static void video_release_buffer( picture_t *p_pic )
2161 if( p_pic && !p_pic->i_refcount && p_pic->pf_release && p_pic->p_sys )
2163 video_del_buffer_decoder( (decoder_t *)p_pic->p_sys->p_owner, p_pic );
2165 else if( p_pic && p_pic->i_refcount > 0 ) p_pic->i_refcount--;
2168 static picture_t *video_new_buffer( vlc_object_t *p_this, picture_t **pp_ring,
2169 sout_stream_sys_t *p_sys )
2171 decoder_t *p_dec = (decoder_t *)p_this;
2175 /* Find an empty space in the picture ring buffer */
2176 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2178 if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2180 pp_ring[i]->i_status = RESERVED_PICTURE;
2184 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2186 if( pp_ring[i] == 0 ) break;
2189 if( i == PICTURE_RING_SIZE && p_sys->i_threads >= 1 )
2191 int i_first_pic = p_sys->i_first_pic;
2193 if( p_sys->i_first_pic != p_sys->i_last_pic )
2195 /* Encoder still has stuff to encode, wait to clear-up the list */
2196 while( p_sys->i_first_pic == i_first_pic )
2200 /* Find an empty space in the picture ring buffer */
2201 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2203 if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2205 pp_ring[i]->i_status = RESERVED_PICTURE;
2209 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2211 if( pp_ring[i] == 0 ) break;
2215 if( i == PICTURE_RING_SIZE )
2217 msg_Err( p_this, "decoder/filter is leaking pictures, "
2218 "resetting its ring buffer" );
2220 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2222 pp_ring[i]->pf_release( pp_ring[i] );
2228 p_pic = picture_New( p_dec->fmt_out.video.i_chroma,
2229 p_dec->fmt_out.video.i_width,
2230 p_dec->fmt_out.video.i_height,
2231 p_dec->fmt_out.video.i_aspect );
2232 if( !p_pic ) return NULL;
2233 p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
2234 p_pic->p_sys = calloc( 1, sizeof(picture_sys_t) );
2237 picture_Release( p_pic );
2240 p_pic->pf_release = video_release_buffer;
2241 p_pic->i_refcount = 0;
2247 static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
2249 return video_new_buffer( VLC_OBJECT(p_dec),
2250 p_dec->p_owner->pp_pics, p_dec->p_owner->p_sys );
2253 static picture_t *video_new_buffer_filter( filter_t *p_filter )
2255 return video_new_buffer( VLC_OBJECT(p_filter),
2256 p_filter->p_owner->pp_pics,
2257 p_filter->p_owner->p_sys );
2260 static void video_del_buffer( vlc_object_t *p_this, picture_t *p_pic )
2266 free( p_pic->p_data_orig );
2267 free( p_pic->p_sys );
2272 static void video_del_buffer_decoder( decoder_t *p_decoder, picture_t *p_pic )
2274 VLC_UNUSED(p_decoder);
2275 p_pic->i_refcount = 0;
2276 p_pic->i_status = DESTROYED_PICTURE;
2277 picture_CleanupQuant( p_pic );
2280 static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic )
2282 VLC_UNUSED(p_filter);
2283 p_pic->i_refcount = 0;
2284 p_pic->i_status = DESTROYED_PICTURE;
2285 picture_CleanupQuant( p_pic );
2288 static void video_link_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2291 p_pic->i_refcount++;
2294 static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2297 video_release_buffer( p_pic );
2303 static subpicture_t *spu_new_buffer( decoder_t * );
2304 static void spu_del_buffer( decoder_t *, subpicture_t * );
2306 static int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2308 sout_stream_sys_t *p_sys = p_stream->p_sys;
2314 /* Initialization of decoder structures */
2315 id->p_decoder->pf_decode_sub = NULL;
2316 id->p_decoder->pf_spu_buffer_new = spu_new_buffer;
2317 id->p_decoder->pf_spu_buffer_del = spu_del_buffer;
2318 id->p_decoder->p_owner = (decoder_owner_sys_t *)p_stream;
2319 /* id->p_decoder->p_cfg = p_sys->p_spu_cfg; */
2321 id->p_decoder->p_module =
2322 module_need( id->p_decoder, "decoder", "$codec", 0 );
2324 if( !id->p_decoder->p_module )
2326 msg_Err( p_stream, "cannot find spu decoder" );
2327 return VLC_EGENERIC;
2330 if( !p_sys->b_soverlay )
2333 /* Initialization of encoder format structures */
2334 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2335 id->p_decoder->fmt_in.i_codec );
2337 id->p_encoder->p_cfg = p_sys->p_spu_cfg;
2339 id->p_encoder->p_module =
2340 module_need( id->p_encoder, "encoder", p_sys->psz_senc, true );
2342 if( !id->p_encoder->p_module )
2344 module_unneed( id->p_decoder, id->p_decoder->p_module );
2345 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_senc );
2346 return VLC_EGENERIC;
2352 p_sys->p_spu = spu_Create( p_stream );
2353 spu_Init( p_sys->p_spu );
2359 static void transcode_spu_close( sout_stream_id_t *id)
2362 if( id->p_decoder->p_module )
2363 module_unneed( id->p_decoder, id->p_decoder->p_module );
2366 if( id->p_encoder->p_module )
2367 module_unneed( id->p_encoder, id->p_encoder->p_module );
2370 static int transcode_spu_process( sout_stream_t *p_stream,
2371 sout_stream_id_t *id,
2372 block_t *in, block_t **out )
2374 sout_stream_sys_t *p_sys = p_stream->p_sys;
2375 subpicture_t *p_subpic;
2378 p_subpic = id->p_decoder->pf_decode_sub( id->p_decoder, &in );
2380 return VLC_EGENERIC;
2382 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_SUBTITLE, 1 );
2384 if( p_sys->b_master_sync && p_sys->i_master_drift )
2386 p_subpic->i_start -= p_sys->i_master_drift;
2387 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2390 if( p_sys->b_soverlay )
2392 spu_DisplaySubpicture( p_sys->p_spu, p_subpic );
2398 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2399 spu_del_buffer( id->p_decoder, p_subpic );
2402 block_ChainAppend( out, p_block );
2407 return VLC_EGENERIC;
2410 static subpicture_t *spu_new_buffer( decoder_t *p_dec )
2412 VLC_UNUSED( p_dec );
2413 return subpicture_New();
2416 static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
2418 VLC_UNUSED( p_dec );
2419 subpicture_Delete( p_subpic );
2425 static int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2427 sout_stream_sys_t *p_sys = p_stream->p_sys;
2429 id->p_decoder->fmt_in.i_cat = SPU_ES;
2430 id->p_encoder->fmt_out.psz_language = strdup( "osd" );
2432 if( p_sys->i_osdcodec != 0 || p_sys->psz_osdenc )
2434 msg_Dbg( p_stream, "creating osdmenu transcoding from fcc=`%4.4s' "
2435 "to fcc=`%4.4s'", (char*)&id->p_encoder->fmt_out.i_codec,
2436 (char*)&p_sys->i_osdcodec );
2438 /* Complete destination format */
2439 id->p_encoder->fmt_out.i_codec = p_sys->i_osdcodec;
2442 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2443 VLC_FOURCC('Y','U','V','A') );
2444 id->p_encoder->fmt_in.psz_language = strdup( "osd" );
2446 id->p_encoder->p_cfg = p_sys->p_osd_cfg;
2448 id->p_encoder->p_module =
2449 module_need( id->p_encoder, "encoder", p_sys->psz_osdenc, true );
2451 if( !id->p_encoder->p_module )
2453 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_osdenc );
2457 /* open output stream */
2458 id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_encoder->fmt_out );
2459 id->b_transcode = true;
2461 if( !id->id ) goto error;
2465 msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
2466 (char*)&id->p_decoder->fmt_out.i_codec );
2467 id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_decoder->fmt_out );
2468 id->b_transcode = false;
2470 if( !id->id ) goto error;
2475 p_sys->p_spu = spu_Create( p_stream );
2476 spu_Init( p_sys->p_spu );
2482 msg_Err( p_stream, "starting osd encoding thread failed" );
2483 if( id->p_encoder->p_module )
2484 module_unneed( id->p_encoder, id->p_encoder->p_module );
2485 p_sys->b_osd = false;
2486 return VLC_EGENERIC;
2489 static void transcode_osd_close( sout_stream_t *p_stream, sout_stream_id_t *id)
2491 sout_stream_sys_t *p_sys = p_stream->p_sys;
2496 if( id->p_encoder->p_module )
2497 module_unneed( id->p_encoder, id->p_encoder->p_module );
2499 p_sys->b_osd = false;
2502 static int transcode_osd_process( sout_stream_t *p_stream,
2503 sout_stream_id_t *id,
2504 block_t *in, block_t **out )
2506 sout_stream_sys_t *p_sys = p_stream->p_sys;
2507 subpicture_t *p_subpic = NULL;
2509 /* Check if we have a subpicture to send */
2510 if( p_sys->p_spu && in->i_dts > 0)
2512 p_subpic = spu_SortSubpictures( p_sys->p_spu, in->i_dts, false, false );
2516 msg_Warn( p_stream, "spu channel not initialized, doing it now" );
2519 p_sys->p_spu = spu_Create( p_stream );
2520 spu_Init( p_sys->p_spu );
2526 block_t *p_block = NULL;
2528 if( p_sys->b_master_sync && p_sys->i_master_drift )
2530 p_subpic->i_start -= p_sys->i_master_drift;
2531 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2534 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2535 subpicture_Delete( p_subpic );
2538 p_block->i_dts = p_block->i_pts = in->i_dts;
2539 block_ChainAppend( out, p_block );
2543 return VLC_EGENERIC;