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 config_ChainDestroy( p_sys->p_audio_cfg );
647 free( p_sys->psz_aenc );
649 free( p_sys->psz_vf2 );
651 config_ChainDestroy( p_sys->p_video_cfg );
652 free( p_sys->psz_venc );
654 config_ChainDestroy( p_sys->p_deinterlace_cfg );
655 free( p_sys->psz_deinterlace );
657 config_ChainDestroy( p_sys->p_spu_cfg );
658 free( p_sys->psz_senc );
660 if( p_sys->p_spu ) spu_Destroy( p_sys->p_spu );
662 config_ChainDestroy( p_sys->p_osd_cfg );
663 free( p_sys->psz_osdenc );
665 vlc_object_release( p_sys );
668 struct sout_stream_id_t
672 /* id of the out stream */
676 decoder_t *p_decoder;
679 filter_chain_t *p_f_chain;
680 /* User specified filters */
681 filter_chain_t *p_uf_chain;
684 encoder_t *p_encoder;
687 date_t interpolated_pts;
690 static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
692 sout_stream_sys_t *p_sys = p_stream->p_sys;
693 sout_stream_id_t *id;
695 id = malloc( sizeof( sout_stream_id_t ) );
698 memset( id, 0, sizeof(sout_stream_id_t) );
701 id->p_decoder = NULL;
702 id->p_encoder = NULL;
704 /* Create decoder object */
705 id->p_decoder = vlc_object_create( p_stream, VLC_OBJECT_DECODER );
708 vlc_object_attach( id->p_decoder, p_stream );
709 id->p_decoder->p_module = NULL;
710 id->p_decoder->fmt_in = *p_fmt;
711 id->p_decoder->b_pace_control = true;
713 /* Create encoder object */
714 id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
717 vlc_object_attach( id->p_encoder, p_stream );
718 id->p_encoder->p_module = NULL;
720 /* Create destination format */
721 es_format_Init( &id->p_encoder->fmt_out, p_fmt->i_cat, 0 );
722 id->p_encoder->fmt_out.i_id = p_fmt->i_id;
723 id->p_encoder->fmt_out.i_group = p_fmt->i_group;
724 if( p_fmt->psz_language )
725 id->p_encoder->fmt_out.psz_language = strdup( p_fmt->psz_language );
727 if( p_fmt->i_cat == AUDIO_ES && (p_sys->i_acodec || p_sys->psz_aenc) )
730 "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
731 (char*)&p_fmt->i_codec, (char*)&p_sys->i_acodec );
733 /* Complete destination format */
734 id->p_encoder->fmt_out.i_codec = p_sys->i_acodec;
735 id->p_encoder->fmt_out.audio.i_rate = p_sys->i_sample_rate > 0 ?
736 p_sys->i_sample_rate : p_fmt->audio.i_rate;
737 id->p_encoder->fmt_out.i_bitrate = p_sys->i_abitrate;
738 id->p_encoder->fmt_out.audio.i_bitspersample =
739 p_fmt->audio.i_bitspersample;
740 id->p_encoder->fmt_out.audio.i_channels = p_sys->i_channels > 0 ?
741 p_sys->i_channels : p_fmt->audio.i_channels;
742 /* Sanity check for audio channels */
743 id->p_encoder->fmt_out.audio.i_channels =
744 __MIN( id->p_encoder->fmt_out.audio.i_channels,
745 id->p_decoder->fmt_in.audio.i_channels );
746 id->p_encoder->fmt_out.audio.i_original_channels =
747 id->p_decoder->fmt_in.audio.i_physical_channels;
748 if( id->p_decoder->fmt_in.audio.i_channels ==
749 id->p_encoder->fmt_out.audio.i_channels )
751 id->p_encoder->fmt_out.audio.i_physical_channels =
752 id->p_decoder->fmt_in.audio.i_physical_channels;
756 id->p_encoder->fmt_out.audio.i_physical_channels =
757 pi_channels_maps[id->p_encoder->fmt_out.audio.i_channels];
760 /* Build decoder -> filter -> encoder chain */
761 if( transcode_audio_new( p_stream, id ) )
763 msg_Err( p_stream, "cannot create audio chain" );
767 /* Open output stream */
768 id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_encoder->fmt_out );
769 id->b_transcode = true;
773 transcode_audio_close( id );
777 date_Init( &id->interpolated_pts, p_fmt->audio.i_rate, 1 );
779 else if( p_fmt->i_cat == VIDEO_ES &&
780 (p_sys->i_vcodec != 0 || p_sys->psz_venc) )
783 "creating video transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
784 (char*)&p_fmt->i_codec, (char*)&p_sys->i_vcodec );
786 /* Complete destination format */
787 id->p_encoder->fmt_out.i_codec = p_sys->i_vcodec;
788 id->p_encoder->fmt_out.video.i_width = p_sys->i_width & ~1;
789 id->p_encoder->fmt_out.video.i_height = p_sys->i_height & ~1;
790 id->p_encoder->fmt_out.i_bitrate = p_sys->i_vbitrate;
792 /* Build decoder -> filter -> encoder chain */
793 if( transcode_video_new( p_stream, id ) )
795 msg_Err( p_stream, "cannot create video chain" );
799 /* Stream will be added later on because we don't know
800 * all the characteristics of the decoded stream yet */
801 id->b_transcode = true;
803 if( p_sys->f_fps > 0 )
805 id->p_encoder->fmt_out.video.i_frame_rate =
806 (p_sys->f_fps * 1000) + 0.5;
807 id->p_encoder->fmt_out.video.i_frame_rate_base =
811 else if( ( p_fmt->i_cat == SPU_ES ) &&
812 ( p_sys->i_scodec || p_sys->psz_senc ) )
814 msg_Dbg( p_stream, "creating subtitles transcoding from fcc=`%4.4s' "
815 "to fcc=`%4.4s'", (char*)&p_fmt->i_codec,
816 (char*)&p_sys->i_scodec );
818 /* Complete destination format */
819 id->p_encoder->fmt_out.i_codec = p_sys->i_scodec;
821 /* build decoder -> filter -> encoder */
822 if( transcode_spu_new( p_stream, id ) )
824 msg_Err( p_stream, "cannot create subtitles chain" );
828 /* open output stream */
829 id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_encoder->fmt_out );
830 id->b_transcode = true;
834 transcode_spu_close( id );
838 else if( p_fmt->i_cat == SPU_ES && p_sys->b_soverlay )
840 msg_Dbg( p_stream, "subtitles (fcc=`%4.4s') overlaying",
841 (char*)&p_fmt->i_codec );
843 id->b_transcode = true;
845 /* Build decoder -> filter -> overlaying chain */
846 if( transcode_spu_new( p_stream, id ) )
848 msg_Err( p_stream, "cannot create subtitles chain" );
852 else if( !p_sys->b_osd && (p_sys->i_osdcodec != 0 || p_sys->psz_osdenc) )
854 msg_Dbg( p_stream, "creating osd transcoding from fcc=`%4.4s' "
855 "to fcc=`%4.4s'", (char*)&p_fmt->i_codec,
856 (char*)&p_sys->i_scodec );
858 id->b_transcode = true;
860 /* Create a fake OSD menu elementary stream */
861 if( transcode_osd_new( p_stream, id ) )
863 msg_Err( p_stream, "cannot create osd chain" );
870 msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
871 (char*)&p_fmt->i_codec );
872 id->id = sout_StreamIdAdd( p_sys->p_out, p_fmt );
873 id->b_transcode = false;
875 if( !id->id ) goto error;
885 vlc_object_detach( id->p_decoder );
886 vlc_object_release( id->p_decoder );
887 id->p_decoder = NULL;
892 vlc_object_detach( id->p_encoder );
893 es_format_Clean( &id->p_encoder->fmt_out );
894 vlc_object_release( id->p_encoder );
895 id->p_encoder = NULL;
903 static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
905 sout_stream_sys_t *p_sys = p_stream->p_sys;
907 if( id->b_transcode )
909 switch( id->p_decoder->fmt_in.i_cat )
912 transcode_audio_close( id );
915 transcode_video_close( p_stream, id );
919 transcode_osd_close( p_stream, id );
921 transcode_spu_close( id );
926 if( id->id ) sout_StreamIdDel( p_sys->p_out, id->id );
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;
947 static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
950 sout_stream_sys_t *p_sys = p_stream->p_sys;
951 block_t *p_out = NULL;
953 if( !id->b_transcode )
956 return sout_StreamIdSend( p_sys->p_out, id->id, p_buffer );
958 block_Release( p_buffer );
962 switch( id->p_decoder->fmt_in.i_cat )
965 transcode_audio_process( p_stream, id, p_buffer, &p_out );
969 if( transcode_video_process( p_stream, id, p_buffer, &p_out )
977 /* Transcode OSD menu pictures. */
980 if( transcode_osd_process( p_stream, id, p_buffer, &p_out ) !=
986 else if ( transcode_spu_process( p_stream, id, p_buffer, &p_out ) !=
995 block_Release( p_buffer );
1000 return sout_StreamIdSend( p_sys->p_out, id->id, p_out );
1004 /****************************************************************************
1006 ****************************************************************************/
1007 static inline void video_timer_start( encoder_t * p_encoder )
1009 stats_TimerStart( p_encoder, "encoding video frame",
1010 STATS_TIMER_VIDEO_FRAME_ENCODING );
1013 static inline void video_timer_stop( encoder_t * p_encoder )
1015 stats_TimerStop( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1018 static inline void video_timer_close( encoder_t * p_encoder )
1020 stats_TimerDump( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1021 stats_TimerClean( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1024 static inline void audio_timer_start( encoder_t * p_encoder )
1026 stats_TimerStart( p_encoder, "encoding audio frame",
1027 STATS_TIMER_AUDIO_FRAME_ENCODING );
1030 static inline void audio_timer_stop( encoder_t * p_encoder )
1032 stats_TimerStop( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1035 static inline void audio_timer_close( encoder_t * p_encoder )
1037 stats_TimerDump( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1038 stats_TimerClean( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1041 /****************************************************************************
1042 * decoder reencoder part
1043 ****************************************************************************/
1045 static block_t *transcode_audio_alloc( filter_t *p_filter, int size )
1047 VLC_UNUSED( p_filter );
1048 return block_Alloc( size );
1051 static int transcode_audio_filter_allocation_init( filter_t *p_filter,
1055 p_filter->pf_audio_buffer_new = transcode_audio_alloc;
1059 static int transcode_audio_new( sout_stream_t *p_stream,
1060 sout_stream_id_t *id )
1062 sout_stream_sys_t *p_sys = p_stream->p_sys;
1063 es_format_t fmt_last;
1070 /* Initialization of decoder structures */
1071 id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1072 id->p_decoder->fmt_out.i_extra = 0;
1073 id->p_decoder->fmt_out.p_extra = 0;
1074 id->p_decoder->pf_decode_audio = NULL;
1075 id->p_decoder->pf_aout_buffer_new = audio_new_buffer;
1076 id->p_decoder->pf_aout_buffer_del = audio_del_buffer;
1077 /* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */
1079 id->p_decoder->p_module =
1080 module_need( id->p_decoder, "decoder", "$codec", 0 );
1081 if( !id->p_decoder->p_module )
1083 msg_Err( p_stream, "cannot find audio decoder" );
1084 return VLC_EGENERIC;
1086 id->p_decoder->fmt_out.audio.i_bitspersample =
1087 aout_BitsPerSample( id->p_decoder->fmt_out.i_codec );
1088 fmt_last = id->p_decoder->fmt_out;
1089 /* Fix AAC SBR changing number of channels and sampling rate */
1090 if( !(id->p_decoder->fmt_in.i_codec == VLC_FOURCC('m','p','4','a') &&
1091 fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate &&
1092 fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels) )
1093 fmt_last.audio.i_rate = id->p_decoder->fmt_in.audio.i_rate;
1099 /* Initialization of encoder format structures */
1100 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1101 id->p_decoder->fmt_out.i_codec );
1102 id->p_encoder->fmt_in.audio.i_format = id->p_decoder->fmt_out.i_codec;
1104 id->p_encoder->fmt_in.audio.i_rate = id->p_encoder->fmt_out.audio.i_rate;
1105 id->p_encoder->fmt_in.audio.i_physical_channels =
1106 id->p_encoder->fmt_out.audio.i_physical_channels;
1107 id->p_encoder->fmt_in.audio.i_original_channels =
1108 id->p_encoder->fmt_out.audio.i_original_channels;
1109 id->p_encoder->fmt_in.audio.i_channels =
1110 id->p_encoder->fmt_out.audio.i_channels;
1111 id->p_encoder->fmt_in.audio.i_bitspersample =
1112 aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1114 id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1115 id->p_encoder->p_module =
1116 module_need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1117 if( !id->p_encoder->p_module )
1119 msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)",
1120 p_sys->psz_aenc ? p_sys->psz_aenc : "any",
1121 (char *)&p_sys->i_acodec );
1122 module_unneed( id->p_decoder, id->p_decoder->p_module );
1123 id->p_decoder->p_module = NULL;
1124 return VLC_EGENERIC;
1126 id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1127 id->p_encoder->fmt_in.audio.i_bitspersample =
1128 aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1130 /* Init filter chain */
1131 id->p_f_chain = filter_chain_New( p_stream, "audio filter2", true,
1132 transcode_audio_filter_allocation_init, NULL, NULL );
1133 filter_chain_Reset( id->p_f_chain, &fmt_last, &id->p_encoder->fmt_in );
1135 /* Load conversion filters */
1136 if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels ||
1137 fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1139 /* We'll have to go through fl32 first */
1140 fmt_last.i_codec = fmt_last.audio.i_format = VLC_FOURCC('f','l','3','2');
1141 fmt_last.audio.i_bitspersample = aout_BitsPerSample( fmt_last.i_codec );
1142 filter_chain_AppendFilter( id->p_f_chain, NULL, NULL, NULL, &fmt_last );
1143 fmt_last = *filter_chain_GetFmtOut( id->p_f_chain );
1146 for( i = 0; i < 4; i++ )
1148 if( (fmt_last.audio.i_channels !=
1149 id->p_encoder->fmt_in.audio.i_channels) ||
1150 (fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate) ||
1151 (fmt_last.i_codec != id->p_encoder->fmt_in.i_codec) )
1153 msg_Dbg( p_stream, "Looking for filter "
1154 "(%4.4s->%4.4s, channels %d->%d, rate %d->%d)",
1155 (char *)&fmt_last.i_codec,
1156 (char *)&id->p_encoder->fmt_in.i_codec,
1157 fmt_last.audio.i_channels,
1158 id->p_encoder->fmt_in.audio.i_channels,
1159 fmt_last.audio.i_rate,
1160 id->p_encoder->fmt_in.audio.i_rate );
1161 filter_chain_AppendFilter( id->p_f_chain, NULL, NULL,
1162 &fmt_last, &id->p_encoder->fmt_in );
1163 fmt_last = *filter_chain_GetFmtOut( id->p_f_chain );
1168 /* Final checks to see if conversions were successful */
1169 if( fmt_last.i_codec != id->p_encoder->fmt_in.i_codec )
1171 msg_Err( p_stream, "no audio filter found "
1172 "(%4.4s->%4.4s, channels %d->%d, rate %d->%d)",
1173 (char *)&fmt_last.i_codec,
1174 (char *)&id->p_encoder->fmt_in.i_codec,
1175 fmt_last.audio.i_channels,
1176 id->p_encoder->fmt_in.audio.i_channels,
1177 fmt_last.audio.i_rate,
1178 id->p_encoder->fmt_in.audio.i_rate );
1179 transcode_audio_close( id );
1180 return VLC_EGENERIC;
1183 /* Load user specified audio filters now */
1184 if( p_sys->psz_af2 )
1186 id->p_uf_chain = filter_chain_New( p_stream, "audio filter2", false,
1187 transcode_audio_filter_allocation_init, NULL, NULL );
1188 filter_chain_Reset( id->p_uf_chain, &fmt_last, &id->p_encoder->fmt_in );
1189 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_af2 );
1190 fmt_last = *filter_chain_GetFmtOut( id->p_uf_chain );
1193 if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels )
1196 module_unneed( id->p_encoder, id->p_encoder->p_module );
1197 id->p_encoder->p_module = NULL;
1199 /* This might work, but only if the encoder is restarted */
1200 id->p_encoder->fmt_in.audio.i_channels = fmt_last.audio.i_channels;
1201 id->p_encoder->fmt_out.audio.i_channels = fmt_last.audio.i_channels;
1203 id->p_encoder->fmt_in.audio.i_physical_channels =
1204 id->p_encoder->fmt_in.audio.i_original_channels =
1205 fmt_last.audio.i_physical_channels;
1206 id->p_encoder->fmt_out.audio.i_physical_channels =
1207 id->p_encoder->fmt_out.audio.i_original_channels =
1208 fmt_last.audio.i_physical_channels;
1210 msg_Dbg( p_stream, "number of audio channels for mixing changed, "
1211 "trying to reopen the encoder for mixing %i to %i channels",
1212 fmt_last.audio.i_channels,
1213 id->p_encoder->fmt_in.audio.i_channels );
1215 /* reload encoder */
1216 id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1217 id->p_encoder->p_module =
1218 module_need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1219 if( !id->p_encoder->p_module ||
1220 fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels ||
1221 fmt_last.i_codec != id->p_encoder->fmt_in.i_codec )
1223 if( id->p_encoder->p_module )
1225 module_unneed( id->p_encoder, id->p_encoder->p_module );
1226 id->p_encoder->p_module = NULL;
1228 msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)",
1229 p_sys->psz_aenc ? p_sys->psz_aenc : "any",
1230 (char *)&p_sys->i_acodec );
1231 transcode_audio_close( id );
1232 return VLC_EGENERIC;
1234 id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1235 id->p_encoder->fmt_in.audio.i_bitspersample =
1236 aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1238 msg_Err( p_stream, "no audio filter found for mixing from"
1239 " %i to %i channels", fmt_last.audio.i_channels,
1240 id->p_encoder->fmt_in.audio.i_channels );
1242 transcode_audio_close( id );
1243 return VLC_EGENERIC;
1247 if( fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1249 msg_Err( p_stream, "no audio filter found for resampling from"
1250 " %iHz to %iHz", fmt_last.audio.i_rate,
1251 id->p_encoder->fmt_in.audio.i_rate );
1253 /* FIXME : this might work, but only if the encoder is restarted */
1254 id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;
1255 id->p_encoder->fmt_out.audio.i_rate = fmt_last.audio.i_rate;
1257 transcode_audio_close( id );
1258 return VLC_EGENERIC;
1262 /* FIXME: Hack for mp3 transcoding support */
1263 if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC( 'm','p','3',' ' ) )
1264 id->p_encoder->fmt_out.i_codec = VLC_FOURCC( 'm','p','g','a' );
1269 static void transcode_audio_close( sout_stream_id_t *id )
1271 audio_timer_close( id->p_encoder );
1274 if( id->p_decoder->p_module )
1275 module_unneed( id->p_decoder, id->p_decoder->p_module );
1276 id->p_decoder->p_module = NULL;
1279 if( id->p_encoder->p_module )
1280 module_unneed( id->p_encoder, id->p_encoder->p_module );
1281 id->p_encoder->p_module = NULL;
1285 filter_chain_Delete( id->p_f_chain );
1286 if( id->p_uf_chain )
1287 filter_chain_Delete( id->p_uf_chain );
1290 static int transcode_audio_process( sout_stream_t *p_stream,
1291 sout_stream_id_t *id,
1292 block_t *in, block_t **out )
1294 sout_stream_sys_t *p_sys = p_stream->p_sys;
1295 aout_buffer_t *p_audio_buf;
1296 block_t *p_block, *p_audio_block;
1299 while( (p_audio_buf = id->p_decoder->pf_decode_audio( id->p_decoder,
1302 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_AUDIO, 1 );
1303 if( p_sys->b_master_sync )
1305 mtime_t i_dts = date_Get( &id->interpolated_pts ) + 1;
1306 if ( p_audio_buf->start_date - i_dts > MASTER_SYNC_MAX_DRIFT
1307 || p_audio_buf->start_date - i_dts < -MASTER_SYNC_MAX_DRIFT )
1309 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1310 date_Set( &id->interpolated_pts, p_audio_buf->start_date );
1311 i_dts = p_audio_buf->start_date + 1;
1313 p_sys->i_master_drift = p_audio_buf->start_date - i_dts;
1314 date_Increment( &id->interpolated_pts, p_audio_buf->i_nb_samples );
1315 p_audio_buf->start_date -= p_sys->i_master_drift;
1316 p_audio_buf->end_date -= p_sys->i_master_drift;
1319 p_audio_block = p_audio_buf->p_sys;
1320 p_audio_block->i_buffer = p_audio_buf->i_nb_bytes;
1321 p_audio_block->i_dts = p_audio_block->i_pts =
1322 p_audio_buf->start_date;
1323 p_audio_block->i_length = p_audio_buf->end_date -
1324 p_audio_buf->start_date;
1325 p_audio_block->i_samples = p_audio_buf->i_nb_samples;
1327 /* Run filter chain */
1328 p_audio_block = filter_chain_AudioFilter( id->p_f_chain, p_audio_block );
1329 if( id->p_uf_chain )
1330 p_audio_block = filter_chain_AudioFilter( id->p_uf_chain, p_audio_block );
1331 assert( p_audio_block );
1333 p_audio_buf->p_buffer = p_audio_block->p_buffer;
1334 p_audio_buf->i_nb_bytes = p_audio_block->i_buffer;
1335 p_audio_buf->i_nb_samples = p_audio_block->i_samples;
1336 p_audio_buf->start_date = p_audio_block->i_dts;
1337 p_audio_buf->end_date = p_audio_block->i_dts + p_audio_block->i_length;
1339 audio_timer_start( id->p_encoder );
1340 p_block = id->p_encoder->pf_encode_audio( id->p_encoder, p_audio_buf );
1341 audio_timer_stop( id->p_encoder );
1343 block_ChainAppend( out, p_block );
1344 block_Release( p_audio_block );
1345 free( p_audio_buf );
1351 static void audio_release_buffer( aout_buffer_t *p_buffer )
1353 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1357 static aout_buffer_t *audio_new_buffer( decoder_t *p_dec, int i_samples )
1359 aout_buffer_t *p_buffer;
1363 if( p_dec->fmt_out.audio.i_bitspersample )
1365 i_size = i_samples * p_dec->fmt_out.audio.i_bitspersample / 8 *
1366 p_dec->fmt_out.audio.i_channels;
1368 else if( p_dec->fmt_out.audio.i_bytes_per_frame &&
1369 p_dec->fmt_out.audio.i_frame_length )
1371 i_size = i_samples * p_dec->fmt_out.audio.i_bytes_per_frame /
1372 p_dec->fmt_out.audio.i_frame_length;
1376 i_size = i_samples * 4 * p_dec->fmt_out.audio.i_channels;
1379 p_buffer = malloc( sizeof(aout_buffer_t) );
1380 if( !p_buffer ) return NULL;
1381 p_buffer->b_discontinuity = false;
1382 p_buffer->pf_release = audio_release_buffer;
1383 p_buffer->p_sys = p_block = block_New( p_dec, i_size );
1385 p_buffer->p_buffer = p_block->p_buffer;
1386 p_buffer->i_size = p_buffer->i_nb_bytes = p_block->i_buffer;
1387 p_buffer->i_nb_samples = i_samples;
1388 p_block->i_samples = i_samples;
1393 static void audio_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
1396 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1404 static int transcode_video_filter_allocation_init( filter_t *p_filter,
1407 sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_data;
1410 p_filter->pf_vout_buffer_new = video_new_buffer_filter;
1411 p_filter->pf_vout_buffer_del = video_del_buffer_filter;
1413 p_filter->p_owner = malloc( sizeof(filter_owner_sys_t) );
1414 if( !p_filter->p_owner )
1415 return VLC_EGENERIC;
1417 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1418 p_filter->p_owner->pp_pics[i] = 0;
1419 p_filter->p_owner->p_sys = p_sys;
1424 static void transcode_video_filter_allocation_clear( filter_t *p_filter )
1428 /* Clean-up pictures ring buffer */
1429 for( j = 0; j < PICTURE_RING_SIZE; j++ )
1431 if( p_filter->p_owner->pp_pics[j] )
1432 video_del_buffer( VLC_OBJECT(p_filter),
1433 p_filter->p_owner->pp_pics[j] );
1435 free( p_filter->p_owner );
1438 static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
1440 sout_stream_sys_t *p_sys = p_stream->p_sys;
1444 * Initialization of decoder structures
1446 id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1447 id->p_decoder->fmt_out.i_extra = 0;
1448 id->p_decoder->fmt_out.p_extra = 0;
1449 id->p_decoder->pf_decode_video = NULL;
1450 id->p_decoder->pf_get_cc = NULL;
1451 id->p_decoder->pf_get_cc = 0;
1452 id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
1453 id->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder;
1454 id->p_decoder->pf_picture_link = video_link_picture_decoder;
1455 id->p_decoder->pf_picture_unlink = video_unlink_picture_decoder;
1456 id->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) );
1457 if( !id->p_decoder->p_owner )
1458 return VLC_EGENERIC;
1460 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1461 id->p_decoder->p_owner->pp_pics[i] = 0;
1462 id->p_decoder->p_owner->p_sys = p_sys;
1463 /* id->p_decoder->p_cfg = p_sys->p_video_cfg; */
1465 id->p_decoder->p_module =
1466 module_need( id->p_decoder, "decoder", "$codec", 0 );
1468 if( !id->p_decoder->p_module )
1470 msg_Err( p_stream, "cannot find video decoder" );
1471 free( id->p_decoder->p_owner );
1472 return VLC_EGENERIC;
1477 * Because some info about the decoded input will only be available
1478 * once the first frame is decoded, we actually only test the availability
1479 * of the encoder here.
1482 /* Initialization of encoder format structures */
1483 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1484 id->p_decoder->fmt_out.i_codec );
1485 id->p_encoder->fmt_in.video.i_chroma = id->p_decoder->fmt_out.i_codec;
1487 /* The dimensions will be set properly later on.
1488 * Just put sensible values so we can test an encoder is available. */
1489 id->p_encoder->fmt_in.video.i_width =
1490 id->p_encoder->fmt_out.video.i_width ?:
1491 id->p_decoder->fmt_in.video.i_width ?: 16;
1492 id->p_encoder->fmt_in.video.i_height =
1493 id->p_encoder->fmt_out.video.i_height ?:
1494 id->p_decoder->fmt_in.video.i_height ?: 16;
1495 id->p_encoder->fmt_in.video.i_frame_rate = ENC_FRAMERATE;
1496 id->p_encoder->fmt_in.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1498 id->p_encoder->i_threads = p_sys->i_threads;
1499 id->p_encoder->p_cfg = p_sys->p_video_cfg;
1501 id->p_encoder->p_module =
1502 module_need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1503 if( !id->p_encoder->p_module )
1505 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1506 p_sys->psz_venc ? p_sys->psz_venc : "any",
1507 (char *)&p_sys->i_vcodec );
1508 module_unneed( id->p_decoder, id->p_decoder->p_module );
1509 id->p_decoder->p_module = 0;
1510 free( id->p_decoder->p_owner );
1511 return VLC_EGENERIC;
1514 /* Close the encoder.
1515 * We'll open it only when we have the first frame. */
1516 module_unneed( id->p_encoder, id->p_encoder->p_module );
1517 if( id->p_encoder->fmt_out.p_extra )
1519 free( id->p_encoder->fmt_out.p_extra );
1520 id->p_encoder->fmt_out.p_extra = NULL;
1521 id->p_encoder->fmt_out.i_extra = 0;
1523 id->p_encoder->p_module = NULL;
1525 if( p_sys->i_threads >= 1 )
1527 int i_priority = p_sys->b_high_priority ? VLC_THREAD_PRIORITY_OUTPUT :
1528 VLC_THREAD_PRIORITY_VIDEO;
1529 p_sys->id_video = id;
1530 vlc_mutex_init( &p_sys->lock_out );
1531 vlc_cond_init( &p_sys->cond );
1532 memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) );
1533 p_sys->i_first_pic = 0;
1534 p_sys->i_last_pic = 0;
1535 p_sys->p_buffers = NULL;
1536 p_sys->b_die = p_sys->b_error = 0;
1537 if( vlc_thread_create( p_sys, "encoder", EncoderThread, i_priority,
1540 msg_Err( p_stream, "cannot spawn encoder thread" );
1541 module_unneed( id->p_decoder, id->p_decoder->p_module );
1542 id->p_decoder->p_module = 0;
1543 free( id->p_decoder->p_owner );
1544 return VLC_EGENERIC;
1551 static void transcode_video_encoder_init( sout_stream_t *p_stream,
1552 sout_stream_id_t *id )
1554 sout_stream_sys_t *p_sys = p_stream->p_sys;
1556 /* Calculate scaling
1557 * width/height of source */
1558 int i_src_width = id->p_decoder->fmt_out.video.i_width;
1559 int i_src_height = id->p_decoder->fmt_out.video.i_height;
1561 /* with/height scaling */
1562 float f_scale_width = 1;
1563 float f_scale_height = 1;
1565 /* width/height of output stream */
1570 float f_aspect = (float)id->p_decoder->fmt_out.video.i_aspect /
1573 msg_Dbg( p_stream, "decoder aspect is %i:%i",
1574 id->p_decoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1576 /* Change f_aspect from source frame to source pixel */
1577 f_aspect = f_aspect * i_src_height / i_src_width;
1578 msg_Dbg( p_stream, "source pixel aspect is %f:1", f_aspect );
1580 /* Calculate scaling factor for specified parameters */
1581 if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1582 id->p_encoder->fmt_out.video.i_height <= 0 && p_sys->f_scale )
1584 /* Global scaling. Make sure width will remain a factor of 16 */
1587 int i_new_width = i_src_width * p_sys->f_scale;
1589 if( i_new_width % 16 <= 7 && i_new_width >= 16 )
1590 i_new_width -= i_new_width % 16;
1592 i_new_width += 16 - i_new_width % 16;
1594 f_real_scale = (float)( i_new_width ) / (float) i_src_width;
1596 i_new_height = __MAX( 16, i_src_height * (float)f_real_scale );
1598 f_scale_width = f_real_scale;
1599 f_scale_height = (float) i_new_height / (float) i_src_height;
1601 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1602 id->p_encoder->fmt_out.video.i_height <= 0 )
1604 /* Only width specified */
1605 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1606 f_scale_height = f_scale_width;
1608 else if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1609 id->p_encoder->fmt_out.video.i_height > 0 )
1611 /* Only height specified */
1612 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1613 f_scale_width = f_scale_height;
1615 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1616 id->p_encoder->fmt_out.video.i_height > 0 )
1618 /* Width and height specified */
1619 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1620 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1623 /* check maxwidth and maxheight
1625 if( p_sys->i_maxwidth && f_scale_width > (float)p_sys->i_maxwidth /
1628 f_scale_width = (float)p_sys->i_maxwidth / i_src_width;
1631 if( p_sys->i_maxheight && f_scale_height > (float)p_sys->i_maxheight /
1634 f_scale_height = (float)p_sys->i_maxheight / i_src_height;
1638 /* Change aspect ratio from source pixel to scaled pixel */
1639 f_aspect = f_aspect * f_scale_height / f_scale_width;
1640 msg_Dbg( p_stream, "scaled pixel aspect is %f:1", f_aspect );
1642 /* f_scale_width and f_scale_height are now final */
1643 /* Calculate width, height from scaling
1644 * Make sure its multiple of 2
1646 i_dst_width = 2 * (int)(f_scale_width*i_src_width/2+0.5);
1647 i_dst_height = 2 * (int)(f_scale_height*i_src_height/2+0.5);
1649 /* Change aspect ratio from scaled pixel to output frame */
1650 f_aspect = f_aspect * i_dst_width / i_dst_height;
1652 /* Store calculated values */
1653 id->p_encoder->fmt_out.video.i_width =
1654 id->p_encoder->fmt_out.video.i_visible_width = i_dst_width;
1655 id->p_encoder->fmt_out.video.i_height =
1656 id->p_encoder->fmt_out.video.i_visible_height = i_dst_height;
1658 id->p_encoder->fmt_in.video.i_width =
1659 id->p_encoder->fmt_in.video.i_visible_width = i_dst_width;
1660 id->p_encoder->fmt_in.video.i_height =
1661 id->p_encoder->fmt_in.video.i_visible_height = i_dst_height;
1663 msg_Dbg( p_stream, "source %ix%i, destination %ix%i",
1664 i_src_width, i_src_height,
1665 i_dst_width, i_dst_height
1668 /* Handle frame rate conversion */
1669 if( !id->p_encoder->fmt_out.video.i_frame_rate ||
1670 !id->p_encoder->fmt_out.video.i_frame_rate_base )
1672 if( id->p_decoder->fmt_out.video.i_frame_rate &&
1673 id->p_decoder->fmt_out.video.i_frame_rate_base )
1675 id->p_encoder->fmt_out.video.i_frame_rate =
1676 id->p_decoder->fmt_out.video.i_frame_rate;
1677 id->p_encoder->fmt_out.video.i_frame_rate_base =
1678 id->p_decoder->fmt_out.video.i_frame_rate_base;
1682 /* Pick a sensible default value */
1683 id->p_encoder->fmt_out.video.i_frame_rate = ENC_FRAMERATE;
1684 id->p_encoder->fmt_out.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1688 id->p_encoder->fmt_in.video.i_frame_rate =
1689 id->p_encoder->fmt_out.video.i_frame_rate;
1690 id->p_encoder->fmt_in.video.i_frame_rate_base =
1691 id->p_encoder->fmt_out.video.i_frame_rate_base;
1693 date_Init( &id->interpolated_pts,
1694 id->p_encoder->fmt_out.video.i_frame_rate,
1695 id->p_encoder->fmt_out.video.i_frame_rate_base );
1697 /* Check whether a particular aspect ratio was requested */
1698 if( !id->p_encoder->fmt_out.video.i_aspect )
1700 id->p_encoder->fmt_out.video.i_aspect =
1701 (int)( f_aspect * VOUT_ASPECT_FACTOR + 0.5 );
1703 id->p_encoder->fmt_in.video.i_aspect =
1704 id->p_encoder->fmt_out.video.i_aspect;
1706 msg_Dbg( p_stream, "encoder aspect is %i:%i",
1707 id->p_encoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1709 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1712 static int transcode_video_encoder_open( sout_stream_t *p_stream,
1713 sout_stream_id_t *id )
1715 sout_stream_sys_t *p_sys = p_stream->p_sys;
1718 msg_Dbg( p_stream, "destination (after video filters) %ix%i",
1719 id->p_encoder->fmt_in.video.i_width,
1720 id->p_encoder->fmt_in.video.i_height );
1722 id->p_encoder->p_module =
1723 module_need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1724 if( !id->p_encoder->p_module )
1726 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1727 p_sys->psz_venc ? p_sys->psz_venc : "any",
1728 (char *)&p_sys->i_vcodec );
1729 return VLC_EGENERIC;
1732 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1734 /* Hack for mp2v/mp1v transcoding support */
1735 if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','1','v') ||
1736 id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','2','v') )
1738 id->p_encoder->fmt_out.i_codec = VLC_FOURCC('m','p','g','v');
1741 id->id = sout_StreamIdAdd( p_stream->p_sys->p_out,
1742 &id->p_encoder->fmt_out );
1745 msg_Err( p_stream, "cannot add this stream" );
1746 return VLC_EGENERIC;
1752 static void transcode_video_close( sout_stream_t *p_stream,
1753 sout_stream_id_t *id )
1757 if( p_stream->p_sys->i_threads >= 1 )
1759 vlc_mutex_lock( &p_stream->p_sys->lock_out );
1760 vlc_object_kill( p_stream->p_sys );
1761 vlc_cond_signal( &p_stream->p_sys->cond );
1762 vlc_mutex_unlock( &p_stream->p_sys->lock_out );
1763 vlc_thread_join( p_stream->p_sys );
1764 vlc_mutex_destroy( &p_stream->p_sys->lock_out );
1765 vlc_cond_destroy( &p_stream->p_sys->cond );
1768 video_timer_close( id->p_encoder );
1771 if( id->p_decoder->p_module )
1772 module_unneed( id->p_decoder, id->p_decoder->p_module );
1774 if( id->p_decoder->p_owner )
1776 /* Clean-up pictures ring buffer */
1777 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1779 if( id->p_decoder->p_owner->pp_pics[i] )
1780 video_del_buffer( VLC_OBJECT(id->p_decoder),
1781 id->p_decoder->p_owner->pp_pics[i] );
1783 free( id->p_decoder->p_owner );
1787 if( id->p_encoder->p_module )
1788 module_unneed( id->p_encoder, id->p_encoder->p_module );
1792 filter_chain_Delete( id->p_f_chain );
1793 if( id->p_uf_chain )
1794 filter_chain_Delete( id->p_uf_chain );
1797 static int transcode_video_process( sout_stream_t *p_stream,
1798 sout_stream_id_t *id,
1799 block_t *in, block_t **out )
1801 sout_stream_sys_t *p_sys = p_stream->p_sys;
1802 int i_duplicate = 1;
1803 picture_t *p_pic, *p_pic2 = NULL;
1806 while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
1808 subpicture_t *p_subpic = NULL;
1810 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_VIDEO, 1 );
1812 if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )
1814 mtime_t current_date = mdate();
1815 if( current_date + 50000 > p_pic->date )
1817 msg_Dbg( p_stream, "late picture skipped (%"PRId64")",
1818 current_date + 50000 - p_pic->date );
1819 p_pic->pf_release( p_pic );
1824 if( p_sys->b_master_sync )
1826 mtime_t i_video_drift;
1827 mtime_t i_master_drift = p_sys->i_master_drift;
1830 i_pts = date_Get( &id->interpolated_pts ) + 1;
1831 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1832 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
1834 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1835 date_Set( &id->interpolated_pts, p_pic->date );
1836 i_pts = p_pic->date + 1;
1838 i_video_drift = p_pic->date - i_pts;
1841 /* Set the pts of the frame being encoded */
1842 p_pic->date = i_pts;
1844 if( i_video_drift < (i_master_drift - 50000) )
1847 msg_Dbg( p_stream, "dropping frame (%i)",
1848 (int)(i_video_drift - i_master_drift) );
1850 p_pic->pf_release( p_pic );
1853 else if( i_video_drift > (i_master_drift + 50000) )
1856 msg_Dbg( p_stream, "adding frame (%i)",
1857 (int)(i_video_drift - i_master_drift) );
1863 if( !id->p_encoder->p_module )
1865 transcode_video_encoder_init( p_stream, id );
1867 id->p_f_chain = filter_chain_New( p_stream, "video filter2",
1869 transcode_video_filter_allocation_init,
1870 transcode_video_filter_allocation_clear,
1874 if( p_stream->p_sys->b_deinterlace )
1876 filter_chain_AppendFilter( id->p_f_chain,
1877 p_sys->psz_deinterlace,
1878 p_sys->p_deinterlace_cfg,
1879 &id->p_decoder->fmt_out,
1880 &id->p_decoder->fmt_out );
1883 /* Take care of the scaling and chroma conversions */
1884 if( ( id->p_decoder->fmt_out.video.i_chroma !=
1885 id->p_encoder->fmt_in.video.i_chroma ) ||
1886 ( id->p_decoder->fmt_out.video.i_width !=
1887 id->p_encoder->fmt_in.video.i_width ) ||
1888 ( id->p_decoder->fmt_out.video.i_height !=
1889 id->p_encoder->fmt_in.video.i_height ) )
1891 filter_chain_AppendFilter( id->p_f_chain,
1893 &id->p_decoder->fmt_out,
1894 &id->p_encoder->fmt_in );
1897 if( p_sys->psz_vf2 )
1899 const es_format_t *p_fmt_out;
1900 id->p_uf_chain = filter_chain_New( p_stream, "video filter2",
1902 transcode_video_filter_allocation_init,
1903 transcode_video_filter_allocation_clear,
1905 filter_chain_Reset( id->p_uf_chain, &id->p_encoder->fmt_in,
1906 &id->p_encoder->fmt_in );
1907 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_vf2 );
1908 p_fmt_out = filter_chain_GetFmtOut( id->p_uf_chain );
1909 es_format_Copy( &id->p_encoder->fmt_in, p_fmt_out );
1910 id->p_encoder->fmt_out.video.i_width =
1911 id->p_encoder->fmt_in.video.i_width;
1912 id->p_encoder->fmt_out.video.i_height =
1913 id->p_encoder->fmt_in.video.i_height;
1914 id->p_encoder->fmt_out.video.i_aspect =
1915 id->p_encoder->fmt_in.video.i_aspect;
1918 if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS )
1920 p_pic->pf_release( p_pic );
1921 transcode_video_close( p_stream, id );
1922 id->b_transcode = false;
1923 return VLC_EGENERIC;
1927 /* Run filter chain */
1929 p_pic = filter_chain_VideoFilter( id->p_f_chain, p_pic );
1935 /* Check if we have a subpicture to overlay */
1938 p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date,
1939 false /* Fixme: check if stream is paused */, false );
1940 /* TODO: get another pic */
1943 /* Overlay subpicture */
1948 if( p_pic->i_refcount && !filter_chain_GetLength( id->p_f_chain ) )
1950 /* We can't modify the picture, we need to duplicate it */
1951 picture_t *p_tmp = video_new_buffer_decoder( id->p_decoder );
1954 picture_Copy( p_tmp, p_pic );
1955 p_pic->pf_release( p_pic );
1960 if( filter_chain_GetLength( id->p_f_chain ) > 0 )
1961 fmt = filter_chain_GetFmtOut( id->p_f_chain )->video;
1963 fmt = id->p_decoder->fmt_out.video;
1965 /* FIXME (shouldn't have to be done here) */
1966 fmt.i_sar_num = fmt.i_aspect * fmt.i_height / fmt.i_width;
1967 fmt.i_sar_den = VOUT_ASPECT_FACTOR;
1969 spu_RenderSubpictures( p_sys->p_spu, p_pic, &fmt,
1970 p_subpic, &id->p_decoder->fmt_out.video, false );
1973 /* Run user specified filter chain */
1974 if( id->p_uf_chain )
1975 p_pic = filter_chain_VideoFilter( id->p_uf_chain, p_pic );
1977 if( p_sys->i_threads == 0 )
1981 video_timer_start( id->p_encoder );
1982 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
1983 video_timer_stop( id->p_encoder );
1985 block_ChainAppend( out, p_block );
1988 if( p_sys->b_master_sync )
1990 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
1991 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1992 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
1994 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1995 date_Set( &id->interpolated_pts, p_pic->date );
1996 i_pts = p_pic->date + 1;
1998 date_Increment( &id->interpolated_pts, 1 );
2001 if( p_sys->b_master_sync && i_duplicate > 1 )
2003 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
2004 if( (p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT)
2005 || ((p_pic->date - i_pts) < -MASTER_SYNC_MAX_DRIFT) )
2007 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2008 date_Set( &id->interpolated_pts, p_pic->date );
2009 i_pts = p_pic->date + 1;
2011 date_Increment( &id->interpolated_pts, 1 );
2013 if( p_sys->i_threads >= 1 )
2015 /* We can't modify the picture, we need to duplicate it */
2016 p_pic2 = video_new_buffer_decoder( id->p_decoder );
2017 if( p_pic2 != NULL )
2019 picture_Copy( p_pic2, p_pic );
2020 p_pic2->date = i_pts;
2026 p_pic->date = i_pts;
2027 video_timer_start( id->p_encoder );
2028 p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);
2029 video_timer_stop( id->p_encoder );
2030 block_ChainAppend( out, p_block );
2034 if( p_sys->i_threads == 0 )
2036 p_pic->pf_release( p_pic );
2040 vlc_mutex_lock( &p_sys->lock_out );
2041 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
2042 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2043 *out = p_sys->p_buffers;
2044 p_sys->p_buffers = NULL;
2045 if( p_pic2 != NULL )
2047 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic2;
2048 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2050 vlc_cond_signal( &p_sys->cond );
2051 vlc_mutex_unlock( &p_sys->lock_out );
2058 static void* EncoderThread( vlc_object_t* p_this )
2060 sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_this;
2061 sout_stream_id_t *id = p_sys->id_video;
2063 int canc = vlc_savecancel ();
2065 while( vlc_object_alive (p_sys) && !p_sys->b_error )
2069 vlc_mutex_lock( &p_sys->lock_out );
2070 while( p_sys->i_last_pic == p_sys->i_first_pic )
2072 vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );
2073 if( !vlc_object_alive (p_sys) || p_sys->b_error ) break;
2075 if( !vlc_object_alive (p_sys) || p_sys->b_error )
2077 vlc_mutex_unlock( &p_sys->lock_out );
2081 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2082 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2083 vlc_mutex_unlock( &p_sys->lock_out );
2085 video_timer_start( id->p_encoder );
2086 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2087 video_timer_stop( id->p_encoder );
2089 vlc_mutex_lock( &p_sys->lock_out );
2090 block_ChainAppend( &p_sys->p_buffers, p_block );
2092 vlc_mutex_unlock( &p_sys->lock_out );
2093 p_pic->pf_release( p_pic );
2096 while( p_sys->i_last_pic != p_sys->i_first_pic )
2098 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2099 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2100 p_pic->pf_release( p_pic );
2102 block_ChainRelease( p_sys->p_buffers );
2104 vlc_restorecancel (canc);
2108 struct picture_sys_t
2110 vlc_object_t *p_owner;
2113 static void video_release_buffer( picture_t *p_pic )
2115 if( p_pic && !p_pic->i_refcount && p_pic->pf_release && p_pic->p_sys )
2117 video_del_buffer_decoder( (decoder_t *)p_pic->p_sys->p_owner, p_pic );
2119 else if( p_pic && p_pic->i_refcount > 0 ) p_pic->i_refcount--;
2122 static picture_t *video_new_buffer( vlc_object_t *p_this, picture_t **pp_ring,
2123 sout_stream_sys_t *p_sys )
2125 decoder_t *p_dec = (decoder_t *)p_this;
2129 /* Find an empty space in the picture ring buffer */
2130 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2132 if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2134 pp_ring[i]->i_status = RESERVED_PICTURE;
2138 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2140 if( pp_ring[i] == 0 ) break;
2143 if( i == PICTURE_RING_SIZE && p_sys->i_threads >= 1 )
2145 int i_first_pic = p_sys->i_first_pic;
2147 if( p_sys->i_first_pic != p_sys->i_last_pic )
2149 /* Encoder still has stuff to encode, wait to clear-up the list */
2150 while( p_sys->i_first_pic == i_first_pic )
2154 /* Find an empty space in the picture ring buffer */
2155 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2157 if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2159 pp_ring[i]->i_status = RESERVED_PICTURE;
2163 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2165 if( pp_ring[i] == 0 ) break;
2169 if( i == PICTURE_RING_SIZE )
2171 msg_Err( p_this, "decoder/filter is leaking pictures, "
2172 "resetting its ring buffer" );
2174 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2176 pp_ring[i]->pf_release( pp_ring[i] );
2182 p_pic = picture_New( p_dec->fmt_out.video.i_chroma,
2183 p_dec->fmt_out.video.i_width,
2184 p_dec->fmt_out.video.i_height,
2185 p_dec->fmt_out.video.i_aspect );
2186 if( !p_pic ) return NULL;
2187 p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
2188 p_pic->p_sys = calloc( 1, sizeof(picture_sys_t) );
2191 picture_Release( p_pic );
2194 p_pic->pf_release = video_release_buffer;
2195 p_pic->i_refcount = 0;
2201 static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
2203 return video_new_buffer( VLC_OBJECT(p_dec),
2204 p_dec->p_owner->pp_pics, p_dec->p_owner->p_sys );
2207 static picture_t *video_new_buffer_filter( filter_t *p_filter )
2209 return video_new_buffer( VLC_OBJECT(p_filter),
2210 p_filter->p_owner->pp_pics,
2211 p_filter->p_owner->p_sys );
2214 static void video_del_buffer( vlc_object_t *p_this, picture_t *p_pic )
2220 free( p_pic->p_data_orig );
2221 free( p_pic->p_sys );
2226 static void video_del_buffer_decoder( decoder_t *p_decoder, picture_t *p_pic )
2228 VLC_UNUSED(p_decoder);
2229 p_pic->i_refcount = 0;
2230 p_pic->i_status = DESTROYED_PICTURE;
2231 picture_CleanupQuant( p_pic );
2234 static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic )
2236 VLC_UNUSED(p_filter);
2237 p_pic->i_refcount = 0;
2238 p_pic->i_status = DESTROYED_PICTURE;
2239 picture_CleanupQuant( p_pic );
2242 static void video_link_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2245 p_pic->i_refcount++;
2248 static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2251 video_release_buffer( p_pic );
2257 static subpicture_t *spu_new_buffer( decoder_t * );
2258 static void spu_del_buffer( decoder_t *, subpicture_t * );
2260 static int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2262 sout_stream_sys_t *p_sys = p_stream->p_sys;
2268 /* Initialization of decoder structures */
2269 id->p_decoder->pf_decode_sub = NULL;
2270 id->p_decoder->pf_spu_buffer_new = spu_new_buffer;
2271 id->p_decoder->pf_spu_buffer_del = spu_del_buffer;
2272 id->p_decoder->p_owner = (decoder_owner_sys_t *)p_stream;
2273 /* id->p_decoder->p_cfg = p_sys->p_spu_cfg; */
2275 id->p_decoder->p_module =
2276 module_need( id->p_decoder, "decoder", "$codec", 0 );
2278 if( !id->p_decoder->p_module )
2280 msg_Err( p_stream, "cannot find spu decoder" );
2281 return VLC_EGENERIC;
2284 if( !p_sys->b_soverlay )
2287 /* Initialization of encoder format structures */
2288 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2289 id->p_decoder->fmt_in.i_codec );
2291 id->p_encoder->p_cfg = p_sys->p_spu_cfg;
2293 id->p_encoder->p_module =
2294 module_need( id->p_encoder, "encoder", p_sys->psz_senc, true );
2296 if( !id->p_encoder->p_module )
2298 module_unneed( id->p_decoder, id->p_decoder->p_module );
2299 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_senc );
2300 return VLC_EGENERIC;
2306 p_sys->p_spu = spu_Create( p_stream );
2307 spu_Init( p_sys->p_spu );
2313 static void transcode_spu_close( sout_stream_id_t *id)
2316 if( id->p_decoder->p_module )
2317 module_unneed( id->p_decoder, id->p_decoder->p_module );
2320 if( id->p_encoder->p_module )
2321 module_unneed( id->p_encoder, id->p_encoder->p_module );
2324 static int transcode_spu_process( sout_stream_t *p_stream,
2325 sout_stream_id_t *id,
2326 block_t *in, block_t **out )
2328 sout_stream_sys_t *p_sys = p_stream->p_sys;
2329 subpicture_t *p_subpic;
2332 p_subpic = id->p_decoder->pf_decode_sub( id->p_decoder, &in );
2334 return VLC_EGENERIC;
2336 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_SUBTITLE, 1 );
2338 if( p_sys->b_master_sync && p_sys->i_master_drift )
2340 p_subpic->i_start -= p_sys->i_master_drift;
2341 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2344 if( p_sys->b_soverlay )
2346 spu_DisplaySubpicture( p_sys->p_spu, p_subpic );
2352 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2353 spu_del_buffer( id->p_decoder, p_subpic );
2356 block_ChainAppend( out, p_block );
2361 return VLC_EGENERIC;
2364 static subpicture_t *spu_new_buffer( decoder_t *p_dec )
2366 VLC_UNUSED( p_dec );
2367 return subpicture_New();
2370 static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
2372 VLC_UNUSED( p_dec );
2373 subpicture_Delete( p_subpic );
2379 static int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2381 sout_stream_sys_t *p_sys = p_stream->p_sys;
2383 id->p_decoder->fmt_in.i_cat = SPU_ES;
2384 id->p_encoder->fmt_out.psz_language = strdup( "osd" );
2386 if( p_sys->i_osdcodec != 0 || p_sys->psz_osdenc )
2388 msg_Dbg( p_stream, "creating osdmenu transcoding from fcc=`%4.4s' "
2389 "to fcc=`%4.4s'", (char*)&id->p_encoder->fmt_out.i_codec,
2390 (char*)&p_sys->i_osdcodec );
2392 /* Complete destination format */
2393 id->p_encoder->fmt_out.i_codec = p_sys->i_osdcodec;
2396 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2397 VLC_FOURCC('Y','U','V','A') );
2398 id->p_encoder->fmt_in.psz_language = strdup( "osd" );
2400 id->p_encoder->p_cfg = p_sys->p_osd_cfg;
2402 id->p_encoder->p_module =
2403 module_need( id->p_encoder, "encoder", p_sys->psz_osdenc, true );
2405 if( !id->p_encoder->p_module )
2407 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_osdenc );
2411 /* open output stream */
2412 id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_encoder->fmt_out );
2413 id->b_transcode = true;
2415 if( !id->id ) goto error;
2419 msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
2420 (char*)&id->p_decoder->fmt_out.i_codec );
2421 id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_decoder->fmt_out );
2422 id->b_transcode = false;
2424 if( !id->id ) goto error;
2429 p_sys->p_spu = spu_Create( p_stream );
2430 spu_Init( p_sys->p_spu );
2436 msg_Err( p_stream, "starting osd encoding thread failed" );
2437 if( id->p_encoder->p_module )
2438 module_unneed( id->p_encoder, id->p_encoder->p_module );
2439 p_sys->b_osd = false;
2440 return VLC_EGENERIC;
2443 static void transcode_osd_close( sout_stream_t *p_stream, sout_stream_id_t *id)
2445 sout_stream_sys_t *p_sys = p_stream->p_sys;
2450 if( id->p_encoder->p_module )
2451 module_unneed( id->p_encoder, id->p_encoder->p_module );
2453 p_sys->b_osd = false;
2456 static int transcode_osd_process( sout_stream_t *p_stream,
2457 sout_stream_id_t *id,
2458 block_t *in, block_t **out )
2460 sout_stream_sys_t *p_sys = p_stream->p_sys;
2461 subpicture_t *p_subpic = NULL;
2463 /* Check if we have a subpicture to send */
2464 if( p_sys->p_spu && in->i_dts > 0)
2466 p_subpic = spu_SortSubpictures( p_sys->p_spu, in->i_dts, false, false );
2470 msg_Warn( p_stream, "spu channel not initialized, doing it now" );
2473 p_sys->p_spu = spu_Create( p_stream );
2474 spu_Init( p_sys->p_spu );
2480 block_t *p_block = NULL;
2482 if( p_sys->b_master_sync && p_sys->i_master_drift )
2484 p_subpic->i_start -= p_sys->i_master_drift;
2485 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2488 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2489 subpicture_Delete( p_subpic );
2492 p_block->i_dts = p_block->i_pts = in->i_dts;
2493 block_ChainAppend( out, p_block );
2497 return VLC_EGENERIC;