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 int EncoderThread( struct sout_stream_sys_t * p_sys );
290 static 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 filter_chain_AppendFilter( id->p_f_chain, NULL, NULL, &fmt_last, &id->p_encoder->fmt_in );
1199 fmt_last = *filter_chain_GetFmtOut( id->p_f_chain );
1203 /* Final checks to see if conversions were successful */
1204 if( fmt_last.i_codec != id->p_encoder->fmt_in.i_codec )
1206 msg_Err( p_stream, "no audio filter found (%4.4s->%4.4s)",
1207 (char *)&fmt_last.i_codec,
1208 (char *)&id->p_encoder->fmt_in.i_codec );
1209 transcode_audio_close( id );
1210 return VLC_EGENERIC;
1213 /* Load user specified audio filters now */
1214 if( p_sys->psz_af2 )
1216 id->p_uf_chain = filter_chain_New( p_stream, "audio filter2", false,
1217 transcode_audio_filter_allocation_init, NULL, NULL );
1218 filter_chain_Reset( id->p_uf_chain, &fmt_last, &id->p_encoder->fmt_in );
1219 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_af2 );
1222 if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels )
1225 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1226 id->p_encoder->p_module = NULL;
1228 /* This might work, but only if the encoder is restarted */
1229 id->p_encoder->fmt_in.audio.i_channels = fmt_last.audio.i_channels;
1230 id->p_encoder->fmt_out.audio.i_channels = fmt_last.audio.i_channels;
1232 id->p_encoder->fmt_in.audio.i_physical_channels =
1233 id->p_encoder->fmt_in.audio.i_original_channels =
1234 fmt_last.audio.i_physical_channels;
1235 id->p_encoder->fmt_out.audio.i_physical_channels =
1236 id->p_encoder->fmt_out.audio.i_original_channels =
1237 fmt_last.audio.i_physical_channels;
1239 msg_Dbg( p_stream, "number of audio channels for mixing changed, "
1240 "trying to reopen the encoder for mixing %i to %i channels",
1241 fmt_last.audio.i_channels,
1242 id->p_encoder->fmt_in.audio.i_channels );
1244 /* reload encoder */
1245 id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1246 id->p_encoder->p_module =
1247 module_Need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1248 if( !id->p_encoder->p_module )
1250 msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)",
1251 p_sys->psz_aenc ? p_sys->psz_aenc : "any",
1252 (char *)&p_sys->i_acodec );
1253 transcode_audio_close( id );
1254 return VLC_EGENERIC;
1256 id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1257 id->p_encoder->fmt_in.audio.i_bitspersample =
1258 aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1260 msg_Err( p_stream, "no audio filter found for mixing from"
1261 " %i to %i channels", fmt_last.audio.i_channels,
1262 id->p_encoder->fmt_in.audio.i_channels );
1264 transcode_audio_close( id );
1265 return VLC_EGENERIC;
1269 if( fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1271 msg_Err( p_stream, "no audio filter found for resampling from"
1272 " %iHz to %iHz", fmt_last.audio.i_rate,
1273 id->p_encoder->fmt_in.audio.i_rate );
1275 /* FIXME : this might work, but only if the encoder is restarted */
1276 id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;
1277 id->p_encoder->fmt_out.audio.i_rate = fmt_last.audio.i_rate;
1279 transcode_audio_close( id );
1280 return VLC_EGENERIC;
1284 /* FIXME: Hack for mp3 transcoding support */
1285 if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC( 'm','p','3',' ' ) )
1286 id->p_encoder->fmt_out.i_codec = VLC_FOURCC( 'm','p','g','a' );
1291 static void transcode_audio_close( sout_stream_id_t *id )
1293 audio_timer_close( id->p_encoder );
1296 if( id->p_decoder->p_module )
1297 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1298 id->p_decoder->p_module = NULL;
1301 if( id->p_encoder->p_module )
1302 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1303 id->p_encoder->p_module = NULL;
1307 filter_chain_Delete( id->p_f_chain );
1308 if( id->p_uf_chain )
1309 filter_chain_Delete( id->p_uf_chain );
1312 static int transcode_audio_process( sout_stream_t *p_stream,
1313 sout_stream_id_t *id,
1314 block_t *in, block_t **out )
1316 sout_stream_sys_t *p_sys = p_stream->p_sys;
1317 aout_buffer_t *p_audio_buf;
1318 block_t *p_block, *p_audio_block;
1321 while( (p_audio_buf = id->p_decoder->pf_decode_audio( id->p_decoder,
1324 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_AUDIO, 1 );
1325 if( p_sys->b_master_sync )
1327 mtime_t i_dts = date_Get( &id->interpolated_pts ) + 1;
1328 if ( p_audio_buf->start_date - i_dts > MASTER_SYNC_MAX_DRIFT
1329 || p_audio_buf->start_date - i_dts < -MASTER_SYNC_MAX_DRIFT )
1331 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1332 date_Set( &id->interpolated_pts, p_audio_buf->start_date );
1333 i_dts = p_audio_buf->start_date + 1;
1335 p_sys->i_master_drift = p_audio_buf->start_date - i_dts;
1336 date_Increment( &id->interpolated_pts, p_audio_buf->i_nb_samples );
1337 p_audio_buf->start_date -= p_sys->i_master_drift;
1338 p_audio_buf->end_date -= p_sys->i_master_drift;
1341 p_audio_block = p_audio_buf->p_sys;
1342 p_audio_block->i_buffer = p_audio_buf->i_nb_bytes;
1343 p_audio_block->i_dts = p_audio_block->i_pts =
1344 p_audio_buf->start_date;
1345 p_audio_block->i_length = p_audio_buf->end_date -
1346 p_audio_buf->start_date;
1347 p_audio_block->i_samples = p_audio_buf->i_nb_samples;
1349 /* Run filter chain */
1350 p_audio_block = filter_chain_AudioFilter( id->p_f_chain, p_audio_block );
1351 if( id->p_uf_chain )
1352 p_audio_block = filter_chain_AudioFilter( id->p_uf_chain, p_audio_block );
1353 assert( p_audio_block );
1355 p_audio_buf->p_buffer = p_audio_block->p_buffer;
1356 p_audio_buf->i_nb_bytes = p_audio_block->i_buffer;
1357 p_audio_buf->i_nb_samples = p_audio_block->i_samples;
1358 p_audio_buf->start_date = p_audio_block->i_dts;
1359 p_audio_buf->end_date = p_audio_block->i_dts + p_audio_block->i_length;
1361 audio_timer_start( id->p_encoder );
1362 p_block = id->p_encoder->pf_encode_audio( id->p_encoder, p_audio_buf );
1363 audio_timer_stop( id->p_encoder );
1365 block_ChainAppend( out, p_block );
1366 block_Release( p_audio_block );
1367 free( p_audio_buf );
1373 static void audio_release_buffer( aout_buffer_t *p_buffer )
1375 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1379 static aout_buffer_t *audio_new_buffer( decoder_t *p_dec, int i_samples )
1381 aout_buffer_t *p_buffer;
1385 if( p_dec->fmt_out.audio.i_bitspersample )
1387 i_size = i_samples * p_dec->fmt_out.audio.i_bitspersample / 8 *
1388 p_dec->fmt_out.audio.i_channels;
1390 else if( p_dec->fmt_out.audio.i_bytes_per_frame &&
1391 p_dec->fmt_out.audio.i_frame_length )
1393 i_size = i_samples * p_dec->fmt_out.audio.i_bytes_per_frame /
1394 p_dec->fmt_out.audio.i_frame_length;
1398 i_size = i_samples * 4 * p_dec->fmt_out.audio.i_channels;
1401 p_buffer = malloc( sizeof(aout_buffer_t) );
1402 if( !p_buffer ) return NULL;
1403 p_buffer->b_discontinuity = false;
1404 p_buffer->pf_release = audio_release_buffer;
1405 p_buffer->p_sys = p_block = block_New( p_dec, i_size );
1407 p_buffer->p_buffer = p_block->p_buffer;
1408 p_buffer->i_size = p_buffer->i_nb_bytes = p_block->i_buffer;
1409 p_buffer->i_nb_samples = i_samples;
1410 p_block->i_samples = i_samples;
1415 static void audio_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
1418 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1426 static int transcode_video_filter_allocation_init( filter_t *p_filter,
1429 sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_data;
1432 p_filter->pf_vout_buffer_new = video_new_buffer_filter;
1433 p_filter->pf_vout_buffer_del = video_del_buffer_filter;
1435 p_filter->p_owner = malloc( sizeof(filter_owner_sys_t) );
1436 if( !p_filter->p_owner )
1437 return VLC_EGENERIC;
1439 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1440 p_filter->p_owner->pp_pics[i] = 0;
1441 p_filter->p_owner->p_sys = p_sys;
1446 static void transcode_video_filter_allocation_clear( filter_t *p_filter )
1450 /* Clean-up pictures ring buffer */
1451 for( j = 0; j < PICTURE_RING_SIZE; j++ )
1453 if( p_filter->p_owner->pp_pics[j] )
1454 video_del_buffer( VLC_OBJECT(p_filter),
1455 p_filter->p_owner->pp_pics[j] );
1457 free( p_filter->p_owner );
1460 static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
1462 sout_stream_sys_t *p_sys = p_stream->p_sys;
1466 * Initialization of decoder structures
1468 id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1469 id->p_decoder->fmt_out.i_extra = 0;
1470 id->p_decoder->fmt_out.p_extra = 0;
1471 id->p_decoder->pf_decode_video = NULL;
1472 id->p_decoder->pf_get_cc = NULL;
1473 id->p_decoder->pf_get_cc = 0;
1474 id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
1475 id->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder;
1476 id->p_decoder->pf_picture_link = video_link_picture_decoder;
1477 id->p_decoder->pf_picture_unlink = video_unlink_picture_decoder;
1478 id->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) );
1479 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1480 id->p_decoder->p_owner->pp_pics[i] = 0;
1481 id->p_decoder->p_owner->p_sys = p_sys;
1482 /* id->p_decoder->p_cfg = p_sys->p_video_cfg; */
1484 id->p_decoder->p_module =
1485 module_Need( id->p_decoder, "decoder", "$codec", 0 );
1487 if( !id->p_decoder->p_module )
1489 msg_Err( p_stream, "cannot find video decoder" );
1490 return VLC_EGENERIC;
1495 * Because some info about the decoded input will only be available
1496 * once the first frame is decoded, we actually only test the availability
1497 * of the encoder here.
1500 /* Initialization of encoder format structures */
1501 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1502 id->p_decoder->fmt_out.i_codec );
1503 id->p_encoder->fmt_in.video.i_chroma = id->p_decoder->fmt_out.i_codec;
1505 /* The dimensions will be set properly later on.
1506 * Just put sensible values so we can test an encoder is available. */
1507 id->p_encoder->fmt_in.video.i_width =
1508 id->p_encoder->fmt_out.video.i_width ?:
1509 id->p_decoder->fmt_in.video.i_width ?: 16;
1510 id->p_encoder->fmt_in.video.i_height =
1511 id->p_encoder->fmt_out.video.i_height ?:
1512 id->p_decoder->fmt_in.video.i_height ?: 16;
1513 id->p_encoder->fmt_in.video.i_frame_rate = ENC_FRAMERATE;
1514 id->p_encoder->fmt_in.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1516 id->p_encoder->i_threads = p_sys->i_threads;
1517 id->p_encoder->p_cfg = p_sys->p_video_cfg;
1519 id->p_encoder->p_module =
1520 module_Need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1521 if( !id->p_encoder->p_module )
1523 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1524 p_sys->psz_venc ? p_sys->psz_venc : "any",
1525 (char *)&p_sys->i_vcodec );
1526 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1527 id->p_decoder->p_module = 0;
1528 return VLC_EGENERIC;
1531 /* Close the encoder.
1532 * We'll open it only when we have the first frame. */
1533 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1534 if( id->p_encoder->fmt_out.p_extra )
1536 free( id->p_encoder->fmt_out.p_extra );
1537 id->p_encoder->fmt_out.p_extra = NULL;
1538 id->p_encoder->fmt_out.i_extra = 0;
1540 id->p_encoder->p_module = NULL;
1542 if( p_sys->i_threads >= 1 )
1544 int i_priority = p_sys->b_high_priority ? VLC_THREAD_PRIORITY_OUTPUT :
1545 VLC_THREAD_PRIORITY_VIDEO;
1546 p_sys->id_video = id;
1547 vlc_mutex_init( &p_sys->lock_out );
1548 vlc_cond_init( p_stream, &p_sys->cond );
1549 memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) );
1550 p_sys->i_first_pic = 0;
1551 p_sys->i_last_pic = 0;
1552 p_sys->p_buffers = NULL;
1553 p_sys->b_die = p_sys->b_error = 0;
1554 if( vlc_thread_create( p_sys, "encoder", EncoderThread, i_priority,
1557 msg_Err( p_stream, "cannot spawn encoder thread" );
1558 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1559 id->p_decoder->p_module = 0;
1560 return VLC_EGENERIC;
1567 static void transcode_video_encoder_init( sout_stream_t *p_stream,
1568 sout_stream_id_t *id )
1570 sout_stream_sys_t *p_sys = p_stream->p_sys;
1572 /* Calculate scaling
1573 * width/height of source */
1574 int i_src_width = id->p_decoder->fmt_out.video.i_width;
1575 int i_src_height = id->p_decoder->fmt_out.video.i_height;
1577 /* with/height scaling */
1578 float f_scale_width = 1;
1579 float f_scale_height = 1;
1581 /* width/height of output stream */
1586 float f_aspect = (float)id->p_decoder->fmt_out.video.i_aspect /
1589 msg_Dbg( p_stream, "decoder aspect is %i:%i",
1590 id->p_decoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1592 /* Change f_aspect from source frame to source pixel */
1593 f_aspect = f_aspect * i_src_height / i_src_width;
1594 msg_Dbg( p_stream, "source pixel aspect is %f:1", f_aspect );
1596 /* Calculate scaling factor for specified parameters */
1597 if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1598 id->p_encoder->fmt_out.video.i_height <= 0 && p_sys->f_scale )
1600 /* Global scaling. Make sure width will remain a factor of 16 */
1603 int i_new_width = i_src_width * p_sys->f_scale;
1605 if( i_new_width % 16 <= 7 && i_new_width >= 16 )
1606 i_new_width -= i_new_width % 16;
1608 i_new_width += 16 - i_new_width % 16;
1610 f_real_scale = (float)( i_new_width ) / (float) i_src_width;
1612 i_new_height = __MAX( 16, i_src_height * (float)f_real_scale );
1614 f_scale_width = f_real_scale;
1615 f_scale_height = (float) i_new_height / (float) i_src_height;
1617 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1618 id->p_encoder->fmt_out.video.i_height <= 0 )
1620 /* Only width specified */
1621 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1622 f_scale_height = f_scale_width;
1624 else if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1625 id->p_encoder->fmt_out.video.i_height > 0 )
1627 /* Only height specified */
1628 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1629 f_scale_width = f_scale_height;
1631 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1632 id->p_encoder->fmt_out.video.i_height > 0 )
1634 /* Width and height specified */
1635 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1636 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1639 /* check maxwidth and maxheight
1641 if( p_sys->i_maxwidth && f_scale_width > (float)p_sys->i_maxwidth /
1644 f_scale_width = (float)p_sys->i_maxwidth / i_src_width;
1647 if( p_sys->i_maxheight && f_scale_height > (float)p_sys->i_maxheight /
1650 f_scale_height = (float)p_sys->i_maxheight / i_src_height;
1654 /* Change aspect ratio from source pixel to scaled pixel */
1655 f_aspect = f_aspect * f_scale_height / f_scale_width;
1656 msg_Dbg( p_stream, "scaled pixel aspect is %f:1", f_aspect );
1658 /* f_scale_width and f_scale_height are now final */
1659 /* Calculate width, height from scaling
1660 * Make sure its multiple of 2
1662 i_dst_width = 2 * (int)(f_scale_width*i_src_width/2+0.5);
1663 i_dst_height = 2 * (int)(f_scale_height*i_src_height/2+0.5);
1665 /* Change aspect ratio from scaled pixel to output frame */
1666 f_aspect = f_aspect * i_dst_width / i_dst_height;
1668 /* Store calculated values */
1669 id->p_encoder->fmt_out.video.i_width =
1670 id->p_encoder->fmt_out.video.i_visible_width = i_dst_width;
1671 id->p_encoder->fmt_out.video.i_height =
1672 id->p_encoder->fmt_out.video.i_visible_height = i_dst_height;
1674 id->p_encoder->fmt_in.video.i_width =
1675 id->p_encoder->fmt_in.video.i_visible_width = i_dst_width;
1676 id->p_encoder->fmt_in.video.i_height =
1677 id->p_encoder->fmt_in.video.i_visible_height = i_dst_height;
1679 msg_Dbg( p_stream, "source %ix%i, destination %ix%i",
1680 i_src_width, i_src_height,
1681 i_dst_width, i_dst_height
1684 /* Handle frame rate conversion */
1685 if( !id->p_encoder->fmt_out.video.i_frame_rate ||
1686 !id->p_encoder->fmt_out.video.i_frame_rate_base )
1688 if( id->p_decoder->fmt_out.video.i_frame_rate &&
1689 id->p_decoder->fmt_out.video.i_frame_rate_base )
1691 id->p_encoder->fmt_out.video.i_frame_rate =
1692 id->p_decoder->fmt_out.video.i_frame_rate;
1693 id->p_encoder->fmt_out.video.i_frame_rate_base =
1694 id->p_decoder->fmt_out.video.i_frame_rate_base;
1698 /* Pick a sensible default value */
1699 id->p_encoder->fmt_out.video.i_frame_rate = ENC_FRAMERATE;
1700 id->p_encoder->fmt_out.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1704 id->p_encoder->fmt_in.video.i_frame_rate =
1705 id->p_encoder->fmt_out.video.i_frame_rate;
1706 id->p_encoder->fmt_in.video.i_frame_rate_base =
1707 id->p_encoder->fmt_out.video.i_frame_rate_base;
1709 date_Init( &id->interpolated_pts,
1710 id->p_encoder->fmt_out.video.i_frame_rate,
1711 id->p_encoder->fmt_out.video.i_frame_rate_base );
1713 /* Check whether a particular aspect ratio was requested */
1714 if( !id->p_encoder->fmt_out.video.i_aspect )
1716 id->p_encoder->fmt_out.video.i_aspect =
1717 (int)( f_aspect * VOUT_ASPECT_FACTOR + 0.5 );
1719 id->p_encoder->fmt_in.video.i_aspect =
1720 id->p_encoder->fmt_out.video.i_aspect;
1722 msg_Dbg( p_stream, "encoder aspect is %i:%i",
1723 id->p_encoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1725 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1728 static int transcode_video_encoder_open( sout_stream_t *p_stream,
1729 sout_stream_id_t *id )
1731 sout_stream_sys_t *p_sys = p_stream->p_sys;
1734 msg_Dbg( p_stream, "destination (after video filters) %ix%i",
1735 id->p_encoder->fmt_in.video.i_width,
1736 id->p_encoder->fmt_in.video.i_height );
1738 id->p_encoder->p_module =
1739 module_Need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1740 if( !id->p_encoder->p_module )
1742 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1743 p_sys->psz_venc ? p_sys->psz_venc : "any",
1744 (char *)&p_sys->i_vcodec );
1745 return VLC_EGENERIC;
1748 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1750 /* Hack for mp2v/mp1v transcoding support */
1751 if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','1','v') ||
1752 id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','2','v') )
1754 id->p_encoder->fmt_out.i_codec = VLC_FOURCC('m','p','g','v');
1757 id->id = p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out,
1758 &id->p_encoder->fmt_out );
1761 msg_Err( p_stream, "cannot add this stream" );
1762 return VLC_EGENERIC;
1768 static void transcode_video_close( sout_stream_t *p_stream,
1769 sout_stream_id_t *id )
1773 if( p_stream->p_sys->i_threads >= 1 )
1775 vlc_mutex_lock( &p_stream->p_sys->lock_out );
1776 vlc_object_kill( p_stream->p_sys );
1777 vlc_cond_signal( &p_stream->p_sys->cond );
1778 vlc_mutex_unlock( &p_stream->p_sys->lock_out );
1779 vlc_thread_join( p_stream->p_sys );
1780 vlc_mutex_destroy( &p_stream->p_sys->lock_out );
1781 vlc_cond_destroy( &p_stream->p_sys->cond );
1784 video_timer_close( id->p_encoder );
1787 if( id->p_decoder->p_module )
1788 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1790 if( id->p_decoder->p_owner )
1792 /* Clean-up pictures ring buffer */
1793 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1795 if( id->p_decoder->p_owner->pp_pics[i] )
1796 video_del_buffer( VLC_OBJECT(id->p_decoder),
1797 id->p_decoder->p_owner->pp_pics[i] );
1799 free( id->p_decoder->p_owner );
1803 if( id->p_encoder->p_module )
1804 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1808 filter_chain_Delete( id->p_f_chain );
1809 if( id->p_uf_chain )
1810 filter_chain_Delete( id->p_uf_chain );
1813 static int transcode_video_process( sout_stream_t *p_stream,
1814 sout_stream_id_t *id,
1815 block_t *in, block_t **out )
1817 sout_stream_sys_t *p_sys = p_stream->p_sys;
1818 int i_duplicate = 1;
1819 picture_t *p_pic, *p_pic2 = NULL;
1822 while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
1824 subpicture_t *p_subpic = NULL;
1826 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_VIDEO, 1 );
1828 if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )
1830 mtime_t current_date = mdate();
1831 if( current_date + 50000 > p_pic->date )
1833 msg_Dbg( p_stream, "late picture skipped (%"PRId64")",
1834 current_date + 50000 - p_pic->date );
1835 p_pic->pf_release( p_pic );
1840 if( p_sys->b_master_sync )
1842 mtime_t i_video_drift;
1843 mtime_t i_master_drift = p_sys->i_master_drift;
1846 i_pts = date_Get( &id->interpolated_pts ) + 1;
1847 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1848 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
1850 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1851 date_Set( &id->interpolated_pts, p_pic->date );
1852 i_pts = p_pic->date + 1;
1854 i_video_drift = p_pic->date - i_pts;
1857 /* Set the pts of the frame being encoded */
1858 p_pic->date = i_pts;
1860 if( i_video_drift < (i_master_drift - 50000) )
1863 msg_Dbg( p_stream, "dropping frame (%i)",
1864 (int)(i_video_drift - i_master_drift) );
1866 p_pic->pf_release( p_pic );
1869 else if( i_video_drift > (i_master_drift + 50000) )
1872 msg_Dbg( p_stream, "adding frame (%i)",
1873 (int)(i_video_drift - i_master_drift) );
1879 if( !id->p_encoder->p_module )
1881 transcode_video_encoder_init( p_stream, id );
1883 id->p_f_chain = filter_chain_New( p_stream, "video filter2",
1885 transcode_video_filter_allocation_init,
1886 transcode_video_filter_allocation_clear,
1890 if( p_stream->p_sys->b_deinterlace )
1892 filter_chain_AppendFilter( id->p_f_chain,
1893 p_sys->psz_deinterlace,
1894 p_sys->p_deinterlace_cfg,
1895 &id->p_decoder->fmt_out,
1896 &id->p_decoder->fmt_out );
1899 /* Take care of the scaling and chroma conversions */
1900 if( ( id->p_decoder->fmt_out.video.i_chroma !=
1901 id->p_encoder->fmt_in.video.i_chroma ) ||
1902 ( id->p_decoder->fmt_out.video.i_width !=
1903 id->p_encoder->fmt_in.video.i_width ) ||
1904 ( id->p_decoder->fmt_out.video.i_height !=
1905 id->p_encoder->fmt_in.video.i_height ) )
1907 filter_chain_AppendFilter( id->p_f_chain,
1909 &id->p_decoder->fmt_out,
1910 &id->p_encoder->fmt_in );
1913 if( p_sys->psz_vf2 )
1915 const es_format_t *p_fmt_out;
1916 id->p_uf_chain = filter_chain_New( p_stream, "video filter2",
1918 transcode_video_filter_allocation_init,
1919 transcode_video_filter_allocation_clear,
1921 filter_chain_Reset( id->p_uf_chain, &id->p_encoder->fmt_in,
1922 &id->p_encoder->fmt_in );
1923 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_vf2 );
1924 p_fmt_out = filter_chain_GetFmtOut( id->p_uf_chain );
1925 es_format_Copy( &id->p_encoder->fmt_in, p_fmt_out );
1926 id->p_encoder->fmt_out.video.i_width =
1927 id->p_encoder->fmt_in.video.i_width;
1928 id->p_encoder->fmt_out.video.i_height =
1929 id->p_encoder->fmt_in.video.i_height;
1932 if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS )
1934 filter_chain_Delete( id->p_f_chain );
1935 if( id->p_uf_chain )
1936 filter_chain_Delete( id->p_uf_chain );
1937 p_pic->pf_release( p_pic );
1938 transcode_video_close( p_stream, id );
1939 id->b_transcode = false;
1940 return VLC_EGENERIC;
1944 /* Run filter chain */
1946 p_pic = filter_chain_VideoFilter( id->p_f_chain, p_pic );
1952 /* Check if we have a subpicture to overlay */
1955 p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date,
1956 false /* Fixme: check if stream is paused */ );
1957 /* TODO: get another pic */
1960 /* Overlay subpicture */
1963 int i_scale_width, i_scale_height;
1966 i_scale_width = id->p_encoder->fmt_in.video.i_width * 1000 /
1967 id->p_decoder->fmt_out.video.i_width;
1968 i_scale_height = id->p_encoder->fmt_in.video.i_height * 1000 /
1969 id->p_decoder->fmt_out.video.i_height;
1971 if( p_pic->i_refcount && !filter_chain_GetLength( id->p_f_chain ) )
1973 /* We can't modify the picture, we need to duplicate it */
1974 picture_t *p_tmp = video_new_buffer_decoder( id->p_decoder );
1977 vout_CopyPicture( p_stream, p_tmp, p_pic );
1978 p_pic->pf_release( p_pic );
1983 if( filter_chain_GetLength( id->p_f_chain ) > 0 )
1984 fmt = filter_chain_GetFmtOut( id->p_f_chain )->video;
1986 fmt = id->p_decoder->fmt_out.video;
1988 /* FIXME (shouldn't have to be done here) */
1989 fmt.i_sar_num = fmt.i_aspect * fmt.i_height / fmt.i_width;
1990 fmt.i_sar_den = VOUT_ASPECT_FACTOR;
1992 spu_RenderSubpictures( p_sys->p_spu, &fmt, p_pic, p_pic, p_subpic,
1993 i_scale_width, i_scale_height );
1996 /* Run user specified filter chain */
1997 if( id->p_uf_chain )
1998 p_pic = filter_chain_VideoFilter( id->p_uf_chain, p_pic );
2000 if( p_sys->i_threads == 0 )
2004 video_timer_start( id->p_encoder );
2005 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2006 video_timer_stop( id->p_encoder );
2008 block_ChainAppend( out, p_block );
2011 if( p_sys->b_master_sync )
2013 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
2014 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
2015 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
2017 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2018 date_Set( &id->interpolated_pts, p_pic->date );
2019 i_pts = p_pic->date + 1;
2021 date_Increment( &id->interpolated_pts, 1 );
2024 if( p_sys->b_master_sync && i_duplicate > 1 )
2026 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
2027 if( (p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT)
2028 || ((p_pic->date - i_pts) < -MASTER_SYNC_MAX_DRIFT) )
2030 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2031 date_Set( &id->interpolated_pts, p_pic->date );
2032 i_pts = p_pic->date + 1;
2034 date_Increment( &id->interpolated_pts, 1 );
2036 if( p_sys->i_threads >= 1 )
2038 /* We can't modify the picture, we need to duplicate it */
2039 p_pic2 = video_new_buffer_decoder( id->p_decoder );
2040 if( p_pic2 != NULL )
2042 vout_CopyPicture( p_stream, p_pic2, p_pic );
2043 p_pic2->date = i_pts;
2049 p_pic->date = i_pts;
2050 video_timer_start( id->p_encoder );
2051 p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);
2052 video_timer_stop( id->p_encoder );
2053 block_ChainAppend( out, p_block );
2057 if( p_sys->i_threads == 0 )
2059 p_pic->pf_release( p_pic );
2063 vlc_mutex_lock( &p_sys->lock_out );
2064 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
2065 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2066 *out = p_sys->p_buffers;
2067 p_sys->p_buffers = NULL;
2068 if( p_pic2 != NULL )
2070 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic2;
2071 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2073 vlc_cond_signal( &p_sys->cond );
2074 vlc_mutex_unlock( &p_sys->lock_out );
2081 static int EncoderThread( sout_stream_sys_t *p_sys )
2083 sout_stream_id_t *id = p_sys->id_video;
2086 while( vlc_object_alive (p_sys) && !p_sys->b_error )
2090 vlc_mutex_lock( &p_sys->lock_out );
2091 while( p_sys->i_last_pic == p_sys->i_first_pic )
2093 vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );
2094 if( !vlc_object_alive (p_sys) || p_sys->b_error ) break;
2096 if( !vlc_object_alive (p_sys) || p_sys->b_error )
2098 vlc_mutex_unlock( &p_sys->lock_out );
2102 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2103 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2104 vlc_mutex_unlock( &p_sys->lock_out );
2106 video_timer_start( id->p_encoder );
2107 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2108 video_timer_stop( id->p_encoder );
2110 vlc_mutex_lock( &p_sys->lock_out );
2111 block_ChainAppend( &p_sys->p_buffers, p_block );
2113 vlc_mutex_unlock( &p_sys->lock_out );
2114 p_pic->pf_release( p_pic );
2117 while( p_sys->i_last_pic != p_sys->i_first_pic )
2119 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2120 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2121 p_pic->pf_release( p_pic );
2123 block_ChainRelease( p_sys->p_buffers );
2128 struct picture_sys_t
2130 vlc_object_t *p_owner;
2133 static void video_release_buffer( picture_t *p_pic )
2135 if( p_pic && !p_pic->i_refcount && p_pic->pf_release && p_pic->p_sys )
2137 video_del_buffer_decoder( (decoder_t *)p_pic->p_sys->p_owner, p_pic );
2139 else if( p_pic && p_pic->i_refcount > 0 ) p_pic->i_refcount--;
2142 static picture_t *video_new_buffer( vlc_object_t *p_this, picture_t **pp_ring,
2143 sout_stream_sys_t *p_sys )
2145 decoder_t *p_dec = (decoder_t *)p_this;
2149 /* Find an empty space in the picture ring buffer */
2150 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2152 if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2154 pp_ring[i]->i_status = RESERVED_PICTURE;
2158 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2160 if( pp_ring[i] == 0 ) break;
2163 if( i == PICTURE_RING_SIZE && p_sys->i_threads >= 1 )
2165 int i_first_pic = p_sys->i_first_pic;
2167 if( p_sys->i_first_pic != p_sys->i_last_pic )
2169 /* Encoder still has stuff to encode, wait to clear-up the list */
2170 while( p_sys->i_first_pic == i_first_pic )
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;
2189 if( i == PICTURE_RING_SIZE )
2191 msg_Err( p_this, "decoder/filter is leaking pictures, "
2192 "resetting its ring buffer" );
2194 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2196 pp_ring[i]->pf_release( pp_ring[i] );
2202 p_pic = malloc( sizeof(picture_t) );
2203 if( !p_pic ) return NULL;
2204 p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
2205 vout_AllocatePicture( VLC_OBJECT(p_dec), p_pic,
2206 p_dec->fmt_out.video.i_chroma,
2207 p_dec->fmt_out.video.i_width,
2208 p_dec->fmt_out.video.i_height,
2209 p_dec->fmt_out.video.i_aspect );
2211 if( !p_pic->i_planes )
2217 p_pic->pf_release = video_release_buffer;
2218 p_pic->p_sys = malloc( sizeof(picture_sys_t) );
2225 p_pic->p_sys->p_owner = p_this;
2226 p_pic->i_status = RESERVED_PICTURE;
2232 static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
2234 return video_new_buffer( VLC_OBJECT(p_dec),
2235 p_dec->p_owner->pp_pics, p_dec->p_owner->p_sys );
2238 static picture_t *video_new_buffer_filter( filter_t *p_filter )
2240 return video_new_buffer( VLC_OBJECT(p_filter),
2241 p_filter->p_owner->pp_pics,
2242 p_filter->p_owner->p_sys );
2245 static void video_del_buffer( vlc_object_t *p_this, picture_t *p_pic )
2250 free( p_pic->p_data_orig );
2251 free( p_pic->p_sys );
2256 static void video_del_buffer_decoder( decoder_t *p_decoder, picture_t *p_pic )
2258 VLC_UNUSED(p_decoder);
2259 p_pic->i_refcount = 0;
2260 p_pic->i_status = DESTROYED_PICTURE;
2263 static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic )
2265 VLC_UNUSED(p_filter);
2266 p_pic->i_refcount = 0;
2267 p_pic->i_status = DESTROYED_PICTURE;
2270 static void video_link_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2273 p_pic->i_refcount++;
2276 static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2279 video_release_buffer( p_pic );
2285 static subpicture_t *spu_new_buffer( decoder_t * );
2286 static void spu_del_buffer( decoder_t *, subpicture_t * );
2288 static int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2290 sout_stream_sys_t *p_sys = p_stream->p_sys;
2296 /* Initialization of decoder structures */
2297 id->p_decoder->pf_decode_sub = NULL;
2298 id->p_decoder->pf_spu_buffer_new = spu_new_buffer;
2299 id->p_decoder->pf_spu_buffer_del = spu_del_buffer;
2300 id->p_decoder->p_owner = (decoder_owner_sys_t *)p_stream;
2301 /* id->p_decoder->p_cfg = p_sys->p_spu_cfg; */
2303 id->p_decoder->p_module =
2304 module_Need( id->p_decoder, "decoder", "$codec", 0 );
2306 if( !id->p_decoder->p_module )
2308 msg_Err( p_stream, "cannot find spu decoder" );
2309 return VLC_EGENERIC;
2312 if( !p_sys->b_soverlay )
2315 /* Initialization of encoder format structures */
2316 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2317 id->p_decoder->fmt_in.i_codec );
2319 id->p_encoder->p_cfg = p_sys->p_spu_cfg;
2321 id->p_encoder->p_module =
2322 module_Need( id->p_encoder, "encoder", p_sys->psz_senc, true );
2324 if( !id->p_encoder->p_module )
2326 module_Unneed( id->p_decoder, id->p_decoder->p_module );
2327 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_senc );
2328 return VLC_EGENERIC;
2334 p_sys->p_spu = spu_Create( p_stream );
2335 spu_Init( p_sys->p_spu );
2341 static void transcode_spu_close( sout_stream_id_t *id)
2344 if( id->p_decoder->p_module )
2345 module_Unneed( id->p_decoder, id->p_decoder->p_module );
2348 if( id->p_encoder->p_module )
2349 module_Unneed( id->p_encoder, id->p_encoder->p_module );
2352 static int transcode_spu_process( sout_stream_t *p_stream,
2353 sout_stream_id_t *id,
2354 block_t *in, block_t **out )
2356 sout_stream_sys_t *p_sys = p_stream->p_sys;
2357 subpicture_t *p_subpic;
2360 p_subpic = id->p_decoder->pf_decode_sub( id->p_decoder, &in );
2362 return VLC_EGENERIC;
2364 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_SUBTITLE, 1 );
2366 if( p_sys->b_master_sync && p_sys->i_master_drift )
2368 p_subpic->i_start -= p_sys->i_master_drift;
2369 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2372 if( p_sys->b_soverlay )
2374 spu_DisplaySubpicture( p_sys->p_spu, p_subpic );
2380 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2381 spu_del_buffer( id->p_decoder, p_subpic );
2384 block_ChainAppend( out, p_block );
2389 return VLC_EGENERIC;
2392 static subpicture_t *spu_new_buffer( decoder_t *p_dec )
2394 sout_stream_t *p_stream = (sout_stream_t *)p_dec->p_owner;
2395 return spu_CreateSubpicture( p_stream->p_sys->p_spu );
2398 static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
2400 sout_stream_t *p_stream = (sout_stream_t *)p_dec->p_owner;
2401 spu_DestroySubpicture( p_stream->p_sys->p_spu, p_subpic );
2407 static int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2409 sout_stream_sys_t *p_sys = p_stream->p_sys;
2411 id->p_decoder->fmt_in.i_cat = SPU_ES;
2412 id->p_encoder->fmt_out.psz_language = strdup( "osd" );
2414 if( p_sys->i_osdcodec != 0 || p_sys->psz_osdenc )
2416 msg_Dbg( p_stream, "creating osdmenu transcoding from fcc=`%4.4s' "
2417 "to fcc=`%4.4s'", (char*)&id->p_encoder->fmt_out.i_codec,
2418 (char*)&p_sys->i_osdcodec );
2420 /* Complete destination format */
2421 id->p_encoder->fmt_out.i_codec = p_sys->i_osdcodec;
2424 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2425 VLC_FOURCC('Y','U','V','A') );
2426 id->p_encoder->fmt_in.psz_language = strdup( "osd" );
2428 id->p_encoder->p_cfg = p_sys->p_osd_cfg;
2430 id->p_encoder->p_module =
2431 module_Need( id->p_encoder, "encoder", p_sys->psz_osdenc, true );
2433 if( !id->p_encoder->p_module )
2435 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_osdenc );
2439 /* open output stream */
2440 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_encoder->fmt_out );
2441 id->b_transcode = true;
2443 if( !id->id ) goto error;
2447 msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
2448 (char*)&id->p_decoder->fmt_out.i_codec );
2449 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_decoder->fmt_out );
2450 id->b_transcode = false;
2452 if( !id->id ) goto error;
2457 p_sys->p_spu = spu_Create( p_stream );
2458 spu_Init( p_sys->p_spu );
2464 msg_Err( p_stream, "starting osd encoding thread failed" );
2465 if( id->p_encoder->p_module )
2466 module_Unneed( id->p_encoder, id->p_encoder->p_module );
2467 p_sys->b_osd = false;
2468 return VLC_EGENERIC;
2471 static void transcode_osd_close( sout_stream_t *p_stream, sout_stream_id_t *id)
2473 sout_stream_sys_t *p_sys = p_stream->p_sys;
2478 if( id->p_encoder->p_module )
2479 module_Unneed( id->p_encoder, id->p_encoder->p_module );
2481 p_sys->b_osd = false;
2484 static int transcode_osd_process( sout_stream_t *p_stream,
2485 sout_stream_id_t *id,
2486 block_t *in, block_t **out )
2488 sout_stream_sys_t *p_sys = p_stream->p_sys;
2489 subpicture_t *p_subpic = NULL;
2491 /* Check if we have a subpicture to send */
2492 if( p_sys->p_spu && in->i_dts > 0)
2494 p_subpic = spu_SortSubpictures( p_sys->p_spu, in->i_dts, false );
2498 msg_Warn( p_stream, "spu channel not initialized, doing it now" );
2501 p_sys->p_spu = spu_Create( p_stream );
2502 spu_Init( p_sys->p_spu );
2508 block_t *p_block = NULL;
2510 if( p_sys->b_master_sync && p_sys->i_master_drift )
2512 p_subpic->i_start -= p_sys->i_master_drift;
2513 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2516 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2517 spu_DestroySubpicture( p_sys->p_spu, p_subpic );
2520 p_block->i_dts = p_block->i_pts = in->i_dts;
2521 block_ChainAppend( out, p_block );
2525 return VLC_EGENERIC;