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 = p_sys->p_out->pf_add( 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 = p_sys->p_out->pf_add( 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 = p_sys->p_out->pf_add( 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 ) p_sys->p_out->pf_del( 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 p_sys->p_out->pf_send( 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 );
1045 if( p_out ) return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_out );
1049 /****************************************************************************
1051 ****************************************************************************/
1052 static inline void video_timer_start( encoder_t * p_encoder )
1054 stats_TimerStart( p_encoder, "encoding video frame",
1055 STATS_TIMER_VIDEO_FRAME_ENCODING );
1058 static inline void video_timer_stop( encoder_t * p_encoder )
1060 stats_TimerStop( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1063 static inline void video_timer_close( encoder_t * p_encoder )
1065 stats_TimerDump( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1066 stats_TimerClean( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1069 static inline void audio_timer_start( encoder_t * p_encoder )
1071 stats_TimerStart( p_encoder, "encoding audio frame",
1072 STATS_TIMER_AUDIO_FRAME_ENCODING );
1075 static inline void audio_timer_stop( encoder_t * p_encoder )
1077 stats_TimerStop( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1080 static inline void audio_timer_close( encoder_t * p_encoder )
1082 stats_TimerDump( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1083 stats_TimerClean( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1086 /****************************************************************************
1087 * decoder reencoder part
1088 ****************************************************************************/
1090 static block_t *transcode_audio_alloc( filter_t *p_filter, int size )
1092 VLC_UNUSED( p_filter );
1093 return block_Alloc( size );
1096 static int transcode_audio_filter_allocation_init( filter_t *p_filter,
1100 p_filter->pf_audio_buffer_new = transcode_audio_alloc;
1104 static int transcode_audio_new( sout_stream_t *p_stream,
1105 sout_stream_id_t *id )
1107 sout_stream_sys_t *p_sys = p_stream->p_sys;
1108 es_format_t fmt_last;
1115 /* Initialization of decoder structures */
1116 id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1117 id->p_decoder->fmt_out.i_extra = 0;
1118 id->p_decoder->fmt_out.p_extra = 0;
1119 id->p_decoder->pf_decode_audio = NULL;
1120 id->p_decoder->pf_aout_buffer_new = audio_new_buffer;
1121 id->p_decoder->pf_aout_buffer_del = audio_del_buffer;
1122 /* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */
1124 id->p_decoder->p_module =
1125 module_need( id->p_decoder, "decoder", "$codec", 0 );
1126 if( !id->p_decoder->p_module )
1128 msg_Err( p_stream, "cannot find audio decoder" );
1129 return VLC_EGENERIC;
1131 id->p_decoder->fmt_out.audio.i_bitspersample =
1132 aout_BitsPerSample( id->p_decoder->fmt_out.i_codec );
1133 fmt_last = id->p_decoder->fmt_out;
1134 /* Fix AAC SBR changing number of channels and sampling rate */
1135 if( !(id->p_decoder->fmt_in.i_codec == VLC_FOURCC('m','p','4','a') &&
1136 fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate &&
1137 fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels) )
1138 fmt_last.audio.i_rate = id->p_decoder->fmt_in.audio.i_rate;
1144 /* Initialization of encoder format structures */
1145 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1146 id->p_decoder->fmt_out.i_codec );
1147 id->p_encoder->fmt_in.audio.i_format = id->p_decoder->fmt_out.i_codec;
1149 id->p_encoder->fmt_in.audio.i_rate = id->p_encoder->fmt_out.audio.i_rate;
1150 id->p_encoder->fmt_in.audio.i_physical_channels =
1151 id->p_encoder->fmt_out.audio.i_physical_channels;
1152 id->p_encoder->fmt_in.audio.i_original_channels =
1153 id->p_encoder->fmt_out.audio.i_original_channels;
1154 id->p_encoder->fmt_in.audio.i_channels =
1155 id->p_encoder->fmt_out.audio.i_channels;
1156 id->p_encoder->fmt_in.audio.i_bitspersample =
1157 aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1159 id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1160 id->p_encoder->p_module =
1161 module_need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1162 if( !id->p_encoder->p_module )
1164 msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)",
1165 p_sys->psz_aenc ? p_sys->psz_aenc : "any",
1166 (char *)&p_sys->i_acodec );
1167 module_unneed( id->p_decoder, id->p_decoder->p_module );
1168 id->p_decoder->p_module = NULL;
1169 return VLC_EGENERIC;
1171 id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1172 id->p_encoder->fmt_in.audio.i_bitspersample =
1173 aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1175 /* Init filter chain */
1176 id->p_f_chain = filter_chain_New( p_stream, "audio filter2", true,
1177 transcode_audio_filter_allocation_init, NULL, NULL );
1178 filter_chain_Reset( id->p_f_chain, &fmt_last, &id->p_encoder->fmt_in );
1180 /* Load conversion filters */
1181 if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels ||
1182 fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1184 /* We'll have to go through fl32 first */
1185 fmt_last.i_codec = fmt_last.audio.i_format = VLC_FOURCC('f','l','3','2');
1186 fmt_last.audio.i_bitspersample = aout_BitsPerSample( fmt_last.i_codec );
1187 filter_chain_AppendFilter( id->p_f_chain, NULL, NULL, NULL, &fmt_last );
1188 fmt_last = *filter_chain_GetFmtOut( id->p_f_chain );
1191 for( i = 0; i < 4; i++ )
1193 if( (fmt_last.audio.i_channels !=
1194 id->p_encoder->fmt_in.audio.i_channels) ||
1195 (fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate) ||
1196 (fmt_last.i_codec != id->p_encoder->fmt_in.i_codec) )
1198 msg_Dbg( p_stream, "Looking for filter "
1199 "(%4.4s->%4.4s, channels %d->%d, rate %d->%d)",
1200 (char *)&fmt_last.i_codec,
1201 (char *)&id->p_encoder->fmt_in.i_codec,
1202 fmt_last.audio.i_channels,
1203 id->p_encoder->fmt_in.audio.i_channels,
1204 fmt_last.audio.i_rate,
1205 id->p_encoder->fmt_in.audio.i_rate );
1206 filter_chain_AppendFilter( id->p_f_chain, NULL, NULL,
1207 &fmt_last, &id->p_encoder->fmt_in );
1208 fmt_last = *filter_chain_GetFmtOut( id->p_f_chain );
1213 /* Final checks to see if conversions were successful */
1214 if( fmt_last.i_codec != id->p_encoder->fmt_in.i_codec )
1216 msg_Err( p_stream, "no audio filter found "
1217 "(%4.4s->%4.4s, channels %d->%d, rate %d->%d)",
1218 (char *)&fmt_last.i_codec,
1219 (char *)&id->p_encoder->fmt_in.i_codec,
1220 fmt_last.audio.i_channels,
1221 id->p_encoder->fmt_in.audio.i_channels,
1222 fmt_last.audio.i_rate,
1223 id->p_encoder->fmt_in.audio.i_rate );
1224 transcode_audio_close( id );
1225 return VLC_EGENERIC;
1228 /* Load user specified audio filters now */
1229 if( p_sys->psz_af2 )
1231 id->p_uf_chain = filter_chain_New( p_stream, "audio filter2", false,
1232 transcode_audio_filter_allocation_init, NULL, NULL );
1233 filter_chain_Reset( id->p_uf_chain, &fmt_last, &id->p_encoder->fmt_in );
1234 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_af2 );
1235 fmt_last = *filter_chain_GetFmtOut( id->p_uf_chain );
1238 if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels )
1241 module_unneed( id->p_encoder, id->p_encoder->p_module );
1242 id->p_encoder->p_module = NULL;
1244 /* This might work, but only if the encoder is restarted */
1245 id->p_encoder->fmt_in.audio.i_channels = fmt_last.audio.i_channels;
1246 id->p_encoder->fmt_out.audio.i_channels = fmt_last.audio.i_channels;
1248 id->p_encoder->fmt_in.audio.i_physical_channels =
1249 id->p_encoder->fmt_in.audio.i_original_channels =
1250 fmt_last.audio.i_physical_channels;
1251 id->p_encoder->fmt_out.audio.i_physical_channels =
1252 id->p_encoder->fmt_out.audio.i_original_channels =
1253 fmt_last.audio.i_physical_channels;
1255 msg_Dbg( p_stream, "number of audio channels for mixing changed, "
1256 "trying to reopen the encoder for mixing %i to %i channels",
1257 fmt_last.audio.i_channels,
1258 id->p_encoder->fmt_in.audio.i_channels );
1260 /* reload encoder */
1261 id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1262 id->p_encoder->p_module =
1263 module_need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1264 if( !id->p_encoder->p_module ||
1265 fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels ||
1266 fmt_last.i_codec != id->p_encoder->fmt_in.i_codec )
1268 if( id->p_encoder->p_module )
1270 module_unneed( id->p_encoder, id->p_encoder->p_module );
1271 id->p_encoder->p_module = NULL;
1273 msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)",
1274 p_sys->psz_aenc ? p_sys->psz_aenc : "any",
1275 (char *)&p_sys->i_acodec );
1276 transcode_audio_close( id );
1277 return VLC_EGENERIC;
1279 id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1280 id->p_encoder->fmt_in.audio.i_bitspersample =
1281 aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1283 msg_Err( p_stream, "no audio filter found for mixing from"
1284 " %i to %i channels", fmt_last.audio.i_channels,
1285 id->p_encoder->fmt_in.audio.i_channels );
1287 transcode_audio_close( id );
1288 return VLC_EGENERIC;
1292 if( fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1294 msg_Err( p_stream, "no audio filter found for resampling from"
1295 " %iHz to %iHz", fmt_last.audio.i_rate,
1296 id->p_encoder->fmt_in.audio.i_rate );
1298 /* FIXME : this might work, but only if the encoder is restarted */
1299 id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;
1300 id->p_encoder->fmt_out.audio.i_rate = fmt_last.audio.i_rate;
1302 transcode_audio_close( id );
1303 return VLC_EGENERIC;
1307 /* FIXME: Hack for mp3 transcoding support */
1308 if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC( 'm','p','3',' ' ) )
1309 id->p_encoder->fmt_out.i_codec = VLC_FOURCC( 'm','p','g','a' );
1314 static void transcode_audio_close( sout_stream_id_t *id )
1316 audio_timer_close( id->p_encoder );
1319 if( id->p_decoder->p_module )
1320 module_unneed( id->p_decoder, id->p_decoder->p_module );
1321 id->p_decoder->p_module = NULL;
1324 if( id->p_encoder->p_module )
1325 module_unneed( id->p_encoder, id->p_encoder->p_module );
1326 id->p_encoder->p_module = NULL;
1330 filter_chain_Delete( id->p_f_chain );
1331 if( id->p_uf_chain )
1332 filter_chain_Delete( id->p_uf_chain );
1335 static int transcode_audio_process( sout_stream_t *p_stream,
1336 sout_stream_id_t *id,
1337 block_t *in, block_t **out )
1339 sout_stream_sys_t *p_sys = p_stream->p_sys;
1340 aout_buffer_t *p_audio_buf;
1341 block_t *p_block, *p_audio_block;
1344 while( (p_audio_buf = id->p_decoder->pf_decode_audio( id->p_decoder,
1347 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_AUDIO, 1 );
1348 if( p_sys->b_master_sync )
1350 mtime_t i_dts = date_Get( &id->interpolated_pts ) + 1;
1351 if ( p_audio_buf->start_date - i_dts > MASTER_SYNC_MAX_DRIFT
1352 || p_audio_buf->start_date - i_dts < -MASTER_SYNC_MAX_DRIFT )
1354 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1355 date_Set( &id->interpolated_pts, p_audio_buf->start_date );
1356 i_dts = p_audio_buf->start_date + 1;
1358 p_sys->i_master_drift = p_audio_buf->start_date - i_dts;
1359 date_Increment( &id->interpolated_pts, p_audio_buf->i_nb_samples );
1360 p_audio_buf->start_date -= p_sys->i_master_drift;
1361 p_audio_buf->end_date -= p_sys->i_master_drift;
1364 p_audio_block = p_audio_buf->p_sys;
1365 p_audio_block->i_buffer = p_audio_buf->i_nb_bytes;
1366 p_audio_block->i_dts = p_audio_block->i_pts =
1367 p_audio_buf->start_date;
1368 p_audio_block->i_length = p_audio_buf->end_date -
1369 p_audio_buf->start_date;
1370 p_audio_block->i_samples = p_audio_buf->i_nb_samples;
1372 /* Run filter chain */
1373 p_audio_block = filter_chain_AudioFilter( id->p_f_chain, p_audio_block );
1374 if( id->p_uf_chain )
1375 p_audio_block = filter_chain_AudioFilter( id->p_uf_chain, p_audio_block );
1376 assert( p_audio_block );
1378 p_audio_buf->p_buffer = p_audio_block->p_buffer;
1379 p_audio_buf->i_nb_bytes = p_audio_block->i_buffer;
1380 p_audio_buf->i_nb_samples = p_audio_block->i_samples;
1381 p_audio_buf->start_date = p_audio_block->i_dts;
1382 p_audio_buf->end_date = p_audio_block->i_dts + p_audio_block->i_length;
1384 audio_timer_start( id->p_encoder );
1385 p_block = id->p_encoder->pf_encode_audio( id->p_encoder, p_audio_buf );
1386 audio_timer_stop( id->p_encoder );
1388 block_ChainAppend( out, p_block );
1389 block_Release( p_audio_block );
1390 free( p_audio_buf );
1396 static void audio_release_buffer( aout_buffer_t *p_buffer )
1398 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1402 static aout_buffer_t *audio_new_buffer( decoder_t *p_dec, int i_samples )
1404 aout_buffer_t *p_buffer;
1408 if( p_dec->fmt_out.audio.i_bitspersample )
1410 i_size = i_samples * p_dec->fmt_out.audio.i_bitspersample / 8 *
1411 p_dec->fmt_out.audio.i_channels;
1413 else if( p_dec->fmt_out.audio.i_bytes_per_frame &&
1414 p_dec->fmt_out.audio.i_frame_length )
1416 i_size = i_samples * p_dec->fmt_out.audio.i_bytes_per_frame /
1417 p_dec->fmt_out.audio.i_frame_length;
1421 i_size = i_samples * 4 * p_dec->fmt_out.audio.i_channels;
1424 p_buffer = malloc( sizeof(aout_buffer_t) );
1425 if( !p_buffer ) return NULL;
1426 p_buffer->b_discontinuity = false;
1427 p_buffer->pf_release = audio_release_buffer;
1428 p_buffer->p_sys = p_block = block_New( p_dec, i_size );
1430 p_buffer->p_buffer = p_block->p_buffer;
1431 p_buffer->i_size = p_buffer->i_nb_bytes = p_block->i_buffer;
1432 p_buffer->i_nb_samples = i_samples;
1433 p_block->i_samples = i_samples;
1438 static void audio_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
1441 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1449 static int transcode_video_filter_allocation_init( filter_t *p_filter,
1452 sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_data;
1455 p_filter->pf_vout_buffer_new = video_new_buffer_filter;
1456 p_filter->pf_vout_buffer_del = video_del_buffer_filter;
1458 p_filter->p_owner = malloc( sizeof(filter_owner_sys_t) );
1459 if( !p_filter->p_owner )
1460 return VLC_EGENERIC;
1462 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1463 p_filter->p_owner->pp_pics[i] = 0;
1464 p_filter->p_owner->p_sys = p_sys;
1469 static void transcode_video_filter_allocation_clear( filter_t *p_filter )
1473 /* Clean-up pictures ring buffer */
1474 for( j = 0; j < PICTURE_RING_SIZE; j++ )
1476 if( p_filter->p_owner->pp_pics[j] )
1477 video_del_buffer( VLC_OBJECT(p_filter),
1478 p_filter->p_owner->pp_pics[j] );
1480 free( p_filter->p_owner );
1483 static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
1485 sout_stream_sys_t *p_sys = p_stream->p_sys;
1489 * Initialization of decoder structures
1491 id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1492 id->p_decoder->fmt_out.i_extra = 0;
1493 id->p_decoder->fmt_out.p_extra = 0;
1494 id->p_decoder->pf_decode_video = NULL;
1495 id->p_decoder->pf_get_cc = NULL;
1496 id->p_decoder->pf_get_cc = 0;
1497 id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
1498 id->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder;
1499 id->p_decoder->pf_picture_link = video_link_picture_decoder;
1500 id->p_decoder->pf_picture_unlink = video_unlink_picture_decoder;
1501 id->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) );
1502 if( !id->p_decoder->p_owner )
1503 return VLC_EGENERIC;
1505 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1506 id->p_decoder->p_owner->pp_pics[i] = 0;
1507 id->p_decoder->p_owner->p_sys = p_sys;
1508 /* id->p_decoder->p_cfg = p_sys->p_video_cfg; */
1510 id->p_decoder->p_module =
1511 module_need( id->p_decoder, "decoder", "$codec", 0 );
1513 if( !id->p_decoder->p_module )
1515 msg_Err( p_stream, "cannot find video decoder" );
1516 free( id->p_decoder->p_owner );
1517 return VLC_EGENERIC;
1522 * Because some info about the decoded input will only be available
1523 * once the first frame is decoded, we actually only test the availability
1524 * of the encoder here.
1527 /* Initialization of encoder format structures */
1528 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1529 id->p_decoder->fmt_out.i_codec );
1530 id->p_encoder->fmt_in.video.i_chroma = id->p_decoder->fmt_out.i_codec;
1532 /* The dimensions will be set properly later on.
1533 * Just put sensible values so we can test an encoder is available. */
1534 id->p_encoder->fmt_in.video.i_width =
1535 id->p_encoder->fmt_out.video.i_width ?:
1536 id->p_decoder->fmt_in.video.i_width ?: 16;
1537 id->p_encoder->fmt_in.video.i_height =
1538 id->p_encoder->fmt_out.video.i_height ?:
1539 id->p_decoder->fmt_in.video.i_height ?: 16;
1540 id->p_encoder->fmt_in.video.i_frame_rate = ENC_FRAMERATE;
1541 id->p_encoder->fmt_in.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1543 id->p_encoder->i_threads = p_sys->i_threads;
1544 id->p_encoder->p_cfg = p_sys->p_video_cfg;
1546 id->p_encoder->p_module =
1547 module_need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1548 if( !id->p_encoder->p_module )
1550 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1551 p_sys->psz_venc ? p_sys->psz_venc : "any",
1552 (char *)&p_sys->i_vcodec );
1553 module_unneed( id->p_decoder, id->p_decoder->p_module );
1554 id->p_decoder->p_module = 0;
1555 free( id->p_decoder->p_owner );
1556 return VLC_EGENERIC;
1559 /* Close the encoder.
1560 * We'll open it only when we have the first frame. */
1561 module_unneed( id->p_encoder, id->p_encoder->p_module );
1562 if( id->p_encoder->fmt_out.p_extra )
1564 free( id->p_encoder->fmt_out.p_extra );
1565 id->p_encoder->fmt_out.p_extra = NULL;
1566 id->p_encoder->fmt_out.i_extra = 0;
1568 id->p_encoder->p_module = NULL;
1570 if( p_sys->i_threads >= 1 )
1572 int i_priority = p_sys->b_high_priority ? VLC_THREAD_PRIORITY_OUTPUT :
1573 VLC_THREAD_PRIORITY_VIDEO;
1574 p_sys->id_video = id;
1575 vlc_mutex_init( &p_sys->lock_out );
1576 vlc_cond_init( &p_sys->cond );
1577 memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) );
1578 p_sys->i_first_pic = 0;
1579 p_sys->i_last_pic = 0;
1580 p_sys->p_buffers = NULL;
1581 p_sys->b_die = p_sys->b_error = 0;
1582 if( vlc_thread_create( p_sys, "encoder", EncoderThread, i_priority,
1585 msg_Err( p_stream, "cannot spawn encoder thread" );
1586 module_unneed( id->p_decoder, id->p_decoder->p_module );
1587 id->p_decoder->p_module = 0;
1588 free( id->p_decoder->p_owner );
1589 return VLC_EGENERIC;
1596 static void transcode_video_encoder_init( sout_stream_t *p_stream,
1597 sout_stream_id_t *id )
1599 sout_stream_sys_t *p_sys = p_stream->p_sys;
1601 /* Calculate scaling
1602 * width/height of source */
1603 int i_src_width = id->p_decoder->fmt_out.video.i_width;
1604 int i_src_height = id->p_decoder->fmt_out.video.i_height;
1606 /* with/height scaling */
1607 float f_scale_width = 1;
1608 float f_scale_height = 1;
1610 /* width/height of output stream */
1615 float f_aspect = (float)id->p_decoder->fmt_out.video.i_aspect /
1618 msg_Dbg( p_stream, "decoder aspect is %i:%i",
1619 id->p_decoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1621 /* Change f_aspect from source frame to source pixel */
1622 f_aspect = f_aspect * i_src_height / i_src_width;
1623 msg_Dbg( p_stream, "source pixel aspect is %f:1", f_aspect );
1625 /* Calculate scaling factor for specified parameters */
1626 if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1627 id->p_encoder->fmt_out.video.i_height <= 0 && p_sys->f_scale )
1629 /* Global scaling. Make sure width will remain a factor of 16 */
1632 int i_new_width = i_src_width * p_sys->f_scale;
1634 if( i_new_width % 16 <= 7 && i_new_width >= 16 )
1635 i_new_width -= i_new_width % 16;
1637 i_new_width += 16 - i_new_width % 16;
1639 f_real_scale = (float)( i_new_width ) / (float) i_src_width;
1641 i_new_height = __MAX( 16, i_src_height * (float)f_real_scale );
1643 f_scale_width = f_real_scale;
1644 f_scale_height = (float) i_new_height / (float) i_src_height;
1646 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1647 id->p_encoder->fmt_out.video.i_height <= 0 )
1649 /* Only width specified */
1650 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1651 f_scale_height = f_scale_width;
1653 else if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1654 id->p_encoder->fmt_out.video.i_height > 0 )
1656 /* Only height specified */
1657 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1658 f_scale_width = f_scale_height;
1660 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1661 id->p_encoder->fmt_out.video.i_height > 0 )
1663 /* Width and height specified */
1664 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1665 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1668 /* check maxwidth and maxheight
1670 if( p_sys->i_maxwidth && f_scale_width > (float)p_sys->i_maxwidth /
1673 f_scale_width = (float)p_sys->i_maxwidth / i_src_width;
1676 if( p_sys->i_maxheight && f_scale_height > (float)p_sys->i_maxheight /
1679 f_scale_height = (float)p_sys->i_maxheight / i_src_height;
1683 /* Change aspect ratio from source pixel to scaled pixel */
1684 f_aspect = f_aspect * f_scale_height / f_scale_width;
1685 msg_Dbg( p_stream, "scaled pixel aspect is %f:1", f_aspect );
1687 /* f_scale_width and f_scale_height are now final */
1688 /* Calculate width, height from scaling
1689 * Make sure its multiple of 2
1691 i_dst_width = 2 * (int)(f_scale_width*i_src_width/2+0.5);
1692 i_dst_height = 2 * (int)(f_scale_height*i_src_height/2+0.5);
1694 /* Change aspect ratio from scaled pixel to output frame */
1695 f_aspect = f_aspect * i_dst_width / i_dst_height;
1697 /* Store calculated values */
1698 id->p_encoder->fmt_out.video.i_width =
1699 id->p_encoder->fmt_out.video.i_visible_width = i_dst_width;
1700 id->p_encoder->fmt_out.video.i_height =
1701 id->p_encoder->fmt_out.video.i_visible_height = i_dst_height;
1703 id->p_encoder->fmt_in.video.i_width =
1704 id->p_encoder->fmt_in.video.i_visible_width = i_dst_width;
1705 id->p_encoder->fmt_in.video.i_height =
1706 id->p_encoder->fmt_in.video.i_visible_height = i_dst_height;
1708 msg_Dbg( p_stream, "source %ix%i, destination %ix%i",
1709 i_src_width, i_src_height,
1710 i_dst_width, i_dst_height
1713 /* Handle frame rate conversion */
1714 if( !id->p_encoder->fmt_out.video.i_frame_rate ||
1715 !id->p_encoder->fmt_out.video.i_frame_rate_base )
1717 if( id->p_decoder->fmt_out.video.i_frame_rate &&
1718 id->p_decoder->fmt_out.video.i_frame_rate_base )
1720 id->p_encoder->fmt_out.video.i_frame_rate =
1721 id->p_decoder->fmt_out.video.i_frame_rate;
1722 id->p_encoder->fmt_out.video.i_frame_rate_base =
1723 id->p_decoder->fmt_out.video.i_frame_rate_base;
1727 /* Pick a sensible default value */
1728 id->p_encoder->fmt_out.video.i_frame_rate = ENC_FRAMERATE;
1729 id->p_encoder->fmt_out.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1733 id->p_encoder->fmt_in.video.i_frame_rate =
1734 id->p_encoder->fmt_out.video.i_frame_rate;
1735 id->p_encoder->fmt_in.video.i_frame_rate_base =
1736 id->p_encoder->fmt_out.video.i_frame_rate_base;
1738 date_Init( &id->interpolated_pts,
1739 id->p_encoder->fmt_out.video.i_frame_rate,
1740 id->p_encoder->fmt_out.video.i_frame_rate_base );
1742 /* Check whether a particular aspect ratio was requested */
1743 if( !id->p_encoder->fmt_out.video.i_aspect )
1745 id->p_encoder->fmt_out.video.i_aspect =
1746 (int)( f_aspect * VOUT_ASPECT_FACTOR + 0.5 );
1748 id->p_encoder->fmt_in.video.i_aspect =
1749 id->p_encoder->fmt_out.video.i_aspect;
1751 msg_Dbg( p_stream, "encoder aspect is %i:%i",
1752 id->p_encoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1754 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1757 static int transcode_video_encoder_open( sout_stream_t *p_stream,
1758 sout_stream_id_t *id )
1760 sout_stream_sys_t *p_sys = p_stream->p_sys;
1763 msg_Dbg( p_stream, "destination (after video filters) %ix%i",
1764 id->p_encoder->fmt_in.video.i_width,
1765 id->p_encoder->fmt_in.video.i_height );
1767 id->p_encoder->p_module =
1768 module_need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1769 if( !id->p_encoder->p_module )
1771 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1772 p_sys->psz_venc ? p_sys->psz_venc : "any",
1773 (char *)&p_sys->i_vcodec );
1774 return VLC_EGENERIC;
1777 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1779 /* Hack for mp2v/mp1v transcoding support */
1780 if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','1','v') ||
1781 id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','2','v') )
1783 id->p_encoder->fmt_out.i_codec = VLC_FOURCC('m','p','g','v');
1786 id->id = p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out,
1787 &id->p_encoder->fmt_out );
1790 msg_Err( p_stream, "cannot add this stream" );
1791 return VLC_EGENERIC;
1797 static void transcode_video_close( sout_stream_t *p_stream,
1798 sout_stream_id_t *id )
1802 if( p_stream->p_sys->i_threads >= 1 )
1804 vlc_mutex_lock( &p_stream->p_sys->lock_out );
1805 vlc_object_kill( p_stream->p_sys );
1806 vlc_cond_signal( &p_stream->p_sys->cond );
1807 vlc_mutex_unlock( &p_stream->p_sys->lock_out );
1808 vlc_thread_join( p_stream->p_sys );
1809 vlc_mutex_destroy( &p_stream->p_sys->lock_out );
1810 vlc_cond_destroy( &p_stream->p_sys->cond );
1813 video_timer_close( id->p_encoder );
1816 if( id->p_decoder->p_module )
1817 module_unneed( id->p_decoder, id->p_decoder->p_module );
1819 if( id->p_decoder->p_owner )
1821 /* Clean-up pictures ring buffer */
1822 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1824 if( id->p_decoder->p_owner->pp_pics[i] )
1825 video_del_buffer( VLC_OBJECT(id->p_decoder),
1826 id->p_decoder->p_owner->pp_pics[i] );
1828 free( id->p_decoder->p_owner );
1832 if( id->p_encoder->p_module )
1833 module_unneed( id->p_encoder, id->p_encoder->p_module );
1837 filter_chain_Delete( id->p_f_chain );
1838 if( id->p_uf_chain )
1839 filter_chain_Delete( id->p_uf_chain );
1842 static int transcode_video_process( sout_stream_t *p_stream,
1843 sout_stream_id_t *id,
1844 block_t *in, block_t **out )
1846 sout_stream_sys_t *p_sys = p_stream->p_sys;
1847 int i_duplicate = 1;
1848 picture_t *p_pic, *p_pic2 = NULL;
1851 while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
1853 subpicture_t *p_subpic = NULL;
1855 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_VIDEO, 1 );
1857 if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )
1859 mtime_t current_date = mdate();
1860 if( current_date + 50000 > p_pic->date )
1862 msg_Dbg( p_stream, "late picture skipped (%"PRId64")",
1863 current_date + 50000 - p_pic->date );
1864 p_pic->pf_release( p_pic );
1869 if( p_sys->b_master_sync )
1871 mtime_t i_video_drift;
1872 mtime_t i_master_drift = p_sys->i_master_drift;
1875 i_pts = date_Get( &id->interpolated_pts ) + 1;
1876 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1877 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
1879 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1880 date_Set( &id->interpolated_pts, p_pic->date );
1881 i_pts = p_pic->date + 1;
1883 i_video_drift = p_pic->date - i_pts;
1886 /* Set the pts of the frame being encoded */
1887 p_pic->date = i_pts;
1889 if( i_video_drift < (i_master_drift - 50000) )
1892 msg_Dbg( p_stream, "dropping frame (%i)",
1893 (int)(i_video_drift - i_master_drift) );
1895 p_pic->pf_release( p_pic );
1898 else if( i_video_drift > (i_master_drift + 50000) )
1901 msg_Dbg( p_stream, "adding frame (%i)",
1902 (int)(i_video_drift - i_master_drift) );
1908 if( !id->p_encoder->p_module )
1910 transcode_video_encoder_init( p_stream, id );
1912 id->p_f_chain = filter_chain_New( p_stream, "video filter2",
1914 transcode_video_filter_allocation_init,
1915 transcode_video_filter_allocation_clear,
1919 if( p_stream->p_sys->b_deinterlace )
1921 filter_chain_AppendFilter( id->p_f_chain,
1922 p_sys->psz_deinterlace,
1923 p_sys->p_deinterlace_cfg,
1924 &id->p_decoder->fmt_out,
1925 &id->p_decoder->fmt_out );
1928 /* Take care of the scaling and chroma conversions */
1929 if( ( id->p_decoder->fmt_out.video.i_chroma !=
1930 id->p_encoder->fmt_in.video.i_chroma ) ||
1931 ( id->p_decoder->fmt_out.video.i_width !=
1932 id->p_encoder->fmt_in.video.i_width ) ||
1933 ( id->p_decoder->fmt_out.video.i_height !=
1934 id->p_encoder->fmt_in.video.i_height ) )
1936 filter_chain_AppendFilter( id->p_f_chain,
1938 &id->p_decoder->fmt_out,
1939 &id->p_encoder->fmt_in );
1942 if( p_sys->psz_vf2 )
1944 const es_format_t *p_fmt_out;
1945 id->p_uf_chain = filter_chain_New( p_stream, "video filter2",
1947 transcode_video_filter_allocation_init,
1948 transcode_video_filter_allocation_clear,
1950 filter_chain_Reset( id->p_uf_chain, &id->p_encoder->fmt_in,
1951 &id->p_encoder->fmt_in );
1952 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_vf2 );
1953 p_fmt_out = filter_chain_GetFmtOut( id->p_uf_chain );
1954 es_format_Copy( &id->p_encoder->fmt_in, p_fmt_out );
1955 id->p_encoder->fmt_out.video.i_width =
1956 id->p_encoder->fmt_in.video.i_width;
1957 id->p_encoder->fmt_out.video.i_height =
1958 id->p_encoder->fmt_in.video.i_height;
1959 id->p_encoder->fmt_out.video.i_aspect =
1960 id->p_encoder->fmt_in.video.i_aspect;
1963 if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS )
1965 p_pic->pf_release( p_pic );
1966 transcode_video_close( p_stream, id );
1967 id->b_transcode = false;
1968 return VLC_EGENERIC;
1972 /* Run filter chain */
1974 p_pic = filter_chain_VideoFilter( id->p_f_chain, p_pic );
1980 /* Check if we have a subpicture to overlay */
1983 p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date,
1984 false /* Fixme: check if stream is paused */, false );
1985 /* TODO: get another pic */
1988 /* Overlay subpicture */
1993 if( p_pic->i_refcount && !filter_chain_GetLength( id->p_f_chain ) )
1995 /* We can't modify the picture, we need to duplicate it */
1996 picture_t *p_tmp = video_new_buffer_decoder( id->p_decoder );
1999 picture_Copy( p_tmp, p_pic );
2000 p_pic->pf_release( p_pic );
2005 if( filter_chain_GetLength( id->p_f_chain ) > 0 )
2006 fmt = filter_chain_GetFmtOut( id->p_f_chain )->video;
2008 fmt = id->p_decoder->fmt_out.video;
2010 /* FIXME (shouldn't have to be done here) */
2011 fmt.i_sar_num = fmt.i_aspect * fmt.i_height / fmt.i_width;
2012 fmt.i_sar_den = VOUT_ASPECT_FACTOR;
2014 spu_RenderSubpictures( p_sys->p_spu, p_pic, &fmt,
2015 p_subpic, &id->p_decoder->fmt_out.video, false );
2018 /* Run user specified filter chain */
2019 if( id->p_uf_chain )
2020 p_pic = filter_chain_VideoFilter( id->p_uf_chain, p_pic );
2022 if( p_sys->i_threads == 0 )
2026 video_timer_start( id->p_encoder );
2027 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2028 video_timer_stop( id->p_encoder );
2030 block_ChainAppend( out, p_block );
2033 if( p_sys->b_master_sync )
2035 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
2036 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
2037 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
2039 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2040 date_Set( &id->interpolated_pts, p_pic->date );
2041 i_pts = p_pic->date + 1;
2043 date_Increment( &id->interpolated_pts, 1 );
2046 if( p_sys->b_master_sync && i_duplicate > 1 )
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 );
2058 if( p_sys->i_threads >= 1 )
2060 /* We can't modify the picture, we need to duplicate it */
2061 p_pic2 = video_new_buffer_decoder( id->p_decoder );
2062 if( p_pic2 != NULL )
2064 picture_Copy( p_pic2, p_pic );
2065 p_pic2->date = i_pts;
2071 p_pic->date = i_pts;
2072 video_timer_start( id->p_encoder );
2073 p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);
2074 video_timer_stop( id->p_encoder );
2075 block_ChainAppend( out, p_block );
2079 if( p_sys->i_threads == 0 )
2081 p_pic->pf_release( p_pic );
2085 vlc_mutex_lock( &p_sys->lock_out );
2086 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
2087 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2088 *out = p_sys->p_buffers;
2089 p_sys->p_buffers = NULL;
2090 if( p_pic2 != NULL )
2092 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic2;
2093 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2095 vlc_cond_signal( &p_sys->cond );
2096 vlc_mutex_unlock( &p_sys->lock_out );
2103 static void* EncoderThread( vlc_object_t* p_this )
2105 sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_this;
2106 sout_stream_id_t *id = p_sys->id_video;
2108 int canc = vlc_savecancel ();
2110 while( vlc_object_alive (p_sys) && !p_sys->b_error )
2114 vlc_mutex_lock( &p_sys->lock_out );
2115 while( p_sys->i_last_pic == p_sys->i_first_pic )
2117 vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );
2118 if( !vlc_object_alive (p_sys) || p_sys->b_error ) break;
2120 if( !vlc_object_alive (p_sys) || p_sys->b_error )
2122 vlc_mutex_unlock( &p_sys->lock_out );
2126 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2127 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2128 vlc_mutex_unlock( &p_sys->lock_out );
2130 video_timer_start( id->p_encoder );
2131 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2132 video_timer_stop( id->p_encoder );
2134 vlc_mutex_lock( &p_sys->lock_out );
2135 block_ChainAppend( &p_sys->p_buffers, p_block );
2137 vlc_mutex_unlock( &p_sys->lock_out );
2138 p_pic->pf_release( p_pic );
2141 while( p_sys->i_last_pic != p_sys->i_first_pic )
2143 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2144 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2145 p_pic->pf_release( p_pic );
2147 block_ChainRelease( p_sys->p_buffers );
2149 vlc_restorecancel (canc);
2153 struct picture_sys_t
2155 vlc_object_t *p_owner;
2158 static void video_release_buffer( picture_t *p_pic )
2160 if( p_pic && !p_pic->i_refcount && p_pic->pf_release && p_pic->p_sys )
2162 video_del_buffer_decoder( (decoder_t *)p_pic->p_sys->p_owner, p_pic );
2164 else if( p_pic && p_pic->i_refcount > 0 ) p_pic->i_refcount--;
2167 static picture_t *video_new_buffer( vlc_object_t *p_this, picture_t **pp_ring,
2168 sout_stream_sys_t *p_sys )
2170 decoder_t *p_dec = (decoder_t *)p_this;
2174 /* Find an empty space in the picture ring buffer */
2175 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2177 if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2179 pp_ring[i]->i_status = RESERVED_PICTURE;
2183 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2185 if( pp_ring[i] == 0 ) break;
2188 if( i == PICTURE_RING_SIZE && p_sys->i_threads >= 1 )
2190 int i_first_pic = p_sys->i_first_pic;
2192 if( p_sys->i_first_pic != p_sys->i_last_pic )
2194 /* Encoder still has stuff to encode, wait to clear-up the list */
2195 while( p_sys->i_first_pic == i_first_pic )
2199 /* Find an empty space in the picture ring buffer */
2200 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2202 if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2204 pp_ring[i]->i_status = RESERVED_PICTURE;
2208 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2210 if( pp_ring[i] == 0 ) break;
2214 if( i == PICTURE_RING_SIZE )
2216 msg_Err( p_this, "decoder/filter is leaking pictures, "
2217 "resetting its ring buffer" );
2219 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2221 pp_ring[i]->pf_release( pp_ring[i] );
2227 p_pic = picture_New( p_dec->fmt_out.video.i_chroma,
2228 p_dec->fmt_out.video.i_width,
2229 p_dec->fmt_out.video.i_height,
2230 p_dec->fmt_out.video.i_aspect );
2231 if( !p_pic ) return NULL;
2232 p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
2233 p_pic->p_sys = calloc( 1, sizeof(picture_sys_t) );
2236 picture_Release( p_pic );
2239 p_pic->pf_release = video_release_buffer;
2240 p_pic->i_refcount = 0;
2246 static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
2248 return video_new_buffer( VLC_OBJECT(p_dec),
2249 p_dec->p_owner->pp_pics, p_dec->p_owner->p_sys );
2252 static picture_t *video_new_buffer_filter( filter_t *p_filter )
2254 return video_new_buffer( VLC_OBJECT(p_filter),
2255 p_filter->p_owner->pp_pics,
2256 p_filter->p_owner->p_sys );
2259 static void video_del_buffer( vlc_object_t *p_this, picture_t *p_pic )
2265 free( p_pic->p_data_orig );
2266 free( p_pic->p_sys );
2271 static void video_del_buffer_decoder( decoder_t *p_decoder, picture_t *p_pic )
2273 VLC_UNUSED(p_decoder);
2274 p_pic->i_refcount = 0;
2275 p_pic->i_status = DESTROYED_PICTURE;
2276 picture_CleanupQuant( p_pic );
2279 static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic )
2281 VLC_UNUSED(p_filter);
2282 p_pic->i_refcount = 0;
2283 p_pic->i_status = DESTROYED_PICTURE;
2284 picture_CleanupQuant( p_pic );
2287 static void video_link_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2290 p_pic->i_refcount++;
2293 static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2296 video_release_buffer( p_pic );
2302 static subpicture_t *spu_new_buffer( decoder_t * );
2303 static void spu_del_buffer( decoder_t *, subpicture_t * );
2305 static int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2307 sout_stream_sys_t *p_sys = p_stream->p_sys;
2313 /* Initialization of decoder structures */
2314 id->p_decoder->pf_decode_sub = NULL;
2315 id->p_decoder->pf_spu_buffer_new = spu_new_buffer;
2316 id->p_decoder->pf_spu_buffer_del = spu_del_buffer;
2317 id->p_decoder->p_owner = (decoder_owner_sys_t *)p_stream;
2318 /* id->p_decoder->p_cfg = p_sys->p_spu_cfg; */
2320 id->p_decoder->p_module =
2321 module_need( id->p_decoder, "decoder", "$codec", 0 );
2323 if( !id->p_decoder->p_module )
2325 msg_Err( p_stream, "cannot find spu decoder" );
2326 return VLC_EGENERIC;
2329 if( !p_sys->b_soverlay )
2332 /* Initialization of encoder format structures */
2333 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2334 id->p_decoder->fmt_in.i_codec );
2336 id->p_encoder->p_cfg = p_sys->p_spu_cfg;
2338 id->p_encoder->p_module =
2339 module_need( id->p_encoder, "encoder", p_sys->psz_senc, true );
2341 if( !id->p_encoder->p_module )
2343 module_unneed( id->p_decoder, id->p_decoder->p_module );
2344 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_senc );
2345 return VLC_EGENERIC;
2351 p_sys->p_spu = spu_Create( p_stream );
2352 spu_Init( p_sys->p_spu );
2358 static void transcode_spu_close( sout_stream_id_t *id)
2361 if( id->p_decoder->p_module )
2362 module_unneed( id->p_decoder, id->p_decoder->p_module );
2365 if( id->p_encoder->p_module )
2366 module_unneed( id->p_encoder, id->p_encoder->p_module );
2369 static int transcode_spu_process( sout_stream_t *p_stream,
2370 sout_stream_id_t *id,
2371 block_t *in, block_t **out )
2373 sout_stream_sys_t *p_sys = p_stream->p_sys;
2374 subpicture_t *p_subpic;
2377 p_subpic = id->p_decoder->pf_decode_sub( id->p_decoder, &in );
2379 return VLC_EGENERIC;
2381 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_SUBTITLE, 1 );
2383 if( p_sys->b_master_sync && p_sys->i_master_drift )
2385 p_subpic->i_start -= p_sys->i_master_drift;
2386 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2389 if( p_sys->b_soverlay )
2391 spu_DisplaySubpicture( p_sys->p_spu, p_subpic );
2397 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2398 spu_del_buffer( id->p_decoder, p_subpic );
2401 block_ChainAppend( out, p_block );
2406 return VLC_EGENERIC;
2409 static subpicture_t *spu_new_buffer( decoder_t *p_dec )
2411 VLC_UNUSED( p_dec );
2412 return subpicture_New();
2415 static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
2417 VLC_UNUSED( p_dec );
2418 subpicture_Delete( p_subpic );
2424 static int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2426 sout_stream_sys_t *p_sys = p_stream->p_sys;
2428 id->p_decoder->fmt_in.i_cat = SPU_ES;
2429 id->p_encoder->fmt_out.psz_language = strdup( "osd" );
2431 if( p_sys->i_osdcodec != 0 || p_sys->psz_osdenc )
2433 msg_Dbg( p_stream, "creating osdmenu transcoding from fcc=`%4.4s' "
2434 "to fcc=`%4.4s'", (char*)&id->p_encoder->fmt_out.i_codec,
2435 (char*)&p_sys->i_osdcodec );
2437 /* Complete destination format */
2438 id->p_encoder->fmt_out.i_codec = p_sys->i_osdcodec;
2441 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2442 VLC_FOURCC('Y','U','V','A') );
2443 id->p_encoder->fmt_in.psz_language = strdup( "osd" );
2445 id->p_encoder->p_cfg = p_sys->p_osd_cfg;
2447 id->p_encoder->p_module =
2448 module_need( id->p_encoder, "encoder", p_sys->psz_osdenc, true );
2450 if( !id->p_encoder->p_module )
2452 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_osdenc );
2456 /* open output stream */
2457 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_encoder->fmt_out );
2458 id->b_transcode = true;
2460 if( !id->id ) goto error;
2464 msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
2465 (char*)&id->p_decoder->fmt_out.i_codec );
2466 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_decoder->fmt_out );
2467 id->b_transcode = false;
2469 if( !id->id ) goto error;
2474 p_sys->p_spu = spu_Create( p_stream );
2475 spu_Init( p_sys->p_spu );
2481 msg_Err( p_stream, "starting osd encoding thread failed" );
2482 if( id->p_encoder->p_module )
2483 module_unneed( id->p_encoder, id->p_encoder->p_module );
2484 p_sys->b_osd = false;
2485 return VLC_EGENERIC;
2488 static void transcode_osd_close( sout_stream_t *p_stream, sout_stream_id_t *id)
2490 sout_stream_sys_t *p_sys = p_stream->p_sys;
2495 if( id->p_encoder->p_module )
2496 module_unneed( id->p_encoder, id->p_encoder->p_module );
2498 p_sys->b_osd = false;
2501 static int transcode_osd_process( sout_stream_t *p_stream,
2502 sout_stream_id_t *id,
2503 block_t *in, block_t **out )
2505 sout_stream_sys_t *p_sys = p_stream->p_sys;
2506 subpicture_t *p_subpic = NULL;
2508 /* Check if we have a subpicture to send */
2509 if( p_sys->p_spu && in->i_dts > 0)
2511 p_subpic = spu_SortSubpictures( p_sys->p_spu, in->i_dts, false, false );
2515 msg_Warn( p_stream, "spu channel not initialized, doing it now" );
2518 p_sys->p_spu = spu_Create( p_stream );
2519 spu_Init( p_sys->p_spu );
2525 block_t *p_block = NULL;
2527 if( p_sys->b_master_sync && p_sys->i_master_drift )
2529 p_subpic->i_start -= p_sys->i_master_drift;
2530 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2533 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2534 subpicture_Delete( p_subpic );
2537 p_block->i_dts = p_block->i_pts = in->i_dts;
2538 block_ChainAppend( out, p_block );
2542 return VLC_EGENERIC;