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>
42 #include <vlc_block.h>
43 #include <vlc_filter.h>
48 #define MASTER_SYNC_MAX_DRIFT 100000
52 /*****************************************************************************
54 *****************************************************************************/
55 #define VENC_TEXT N_("Video encoder")
56 #define VENC_LONGTEXT N_( \
57 "This is the video encoder module that will be used (and its associated "\
59 #define VCODEC_TEXT N_("Destination video codec")
60 #define VCODEC_LONGTEXT N_( \
61 "This is the video codec that will be used.")
62 #define VB_TEXT N_("Video bitrate")
63 #define VB_LONGTEXT N_( \
64 "Target bitrate of the transcoded video stream." )
65 #define SCALE_TEXT N_("Video scaling")
66 #define SCALE_LONGTEXT N_( \
67 "Scale factor to apply to the video while transcoding (eg: 0.25)")
68 #define FPS_TEXT N_("Video frame-rate")
69 #define FPS_LONGTEXT N_( \
70 "Target output frame rate for the video stream." )
71 #define DEINTERLACE_TEXT N_("Deinterlace video")
72 #define DEINTERLACE_LONGTEXT N_( \
73 "Deinterlace the video before encoding." )
74 #define DEINTERLACE_MODULE_TEXT N_("Deinterlace module")
75 #define DEINTERLACE_MODULE_LONGTEXT N_( \
76 "Specify the deinterlace module to use." )
77 #define WIDTH_TEXT N_("Video width")
78 #define WIDTH_LONGTEXT N_( \
79 "Output video width." )
80 #define HEIGHT_TEXT N_("Video height")
81 #define HEIGHT_LONGTEXT N_( \
82 "Output video height." )
83 #define MAXWIDTH_TEXT N_("Maximum video width")
84 #define MAXWIDTH_LONGTEXT N_( \
85 "Maximum output video width." )
86 #define MAXHEIGHT_TEXT N_("Maximum video height")
87 #define MAXHEIGHT_LONGTEXT N_( \
88 "Maximum output video height." )
89 #define VFILTER_TEXT N_("Video filter")
90 #define VFILTER_LONGTEXT N_( \
91 "Video filters will be applied to the video streams (after overlays " \
92 "are applied). You must enter a comma-separated list of filters." )
94 #define AENC_TEXT N_("Audio encoder")
95 #define AENC_LONGTEXT N_( \
96 "This is the audio encoder module that will be used (and its associated "\
98 #define ACODEC_TEXT N_("Destination audio codec")
99 #define ACODEC_LONGTEXT N_( \
100 "This is the audio codec that will be used.")
101 #define AB_TEXT N_("Audio bitrate")
102 #define AB_LONGTEXT N_( \
103 "Target bitrate of the transcoded audio stream." )
104 #define ARATE_TEXT N_("Audio sample rate")
105 #define ARATE_LONGTEXT N_( \
106 "Sample rate of the transcoded audio stream (11250, 22500, 44100 or 48000).")
107 #define ACHANS_TEXT N_("Audio channels")
108 #define ACHANS_LONGTEXT N_( \
109 "Number of audio channels in the transcoded streams." )
110 #define AFILTER_TEXT N_("Audio filter")
111 #define AFILTER_LONGTEXT N_( \
112 "Audio filters will be applied to the audio streams (after conversion " \
113 "filters are applied). You must enter a comma-separated list of filters." )
115 #define SENC_TEXT N_("Subtitles encoder")
116 #define SENC_LONGTEXT N_( \
117 "This is the subtitles encoder module that will be used (and its " \
118 "associated options)." )
119 #define SCODEC_TEXT N_("Destination subtitles codec")
120 #define SCODEC_LONGTEXT N_( \
121 "This is the subtitles codec that will be used." )
123 #define SFILTER_TEXT N_("Overlays")
124 #define SFILTER_LONGTEXT N_( \
125 "This allows you to add overlays (also known as \"subpictures\" on the "\
126 "transcoded video stream. The subpictures produced by the filters will "\
127 "be overlayed directly onto the video. You must specify a comma-separated "\
128 "list of subpicture modules" )
130 #define OSD_TEXT N_("OSD menu")
131 #define OSD_LONGTEXT N_(\
132 "Stream the On Screen Display menu (using the osdmenu subpicture module)." )
134 #define THREADS_TEXT N_("Number of threads")
135 #define THREADS_LONGTEXT N_( \
136 "Number of threads used for the transcoding." )
137 #define HP_TEXT N_("High priority")
138 #define HP_LONGTEXT N_( \
139 "Runs the optional encoder thread at the OUTPUT priority instead of " \
142 #define ASYNC_TEXT N_("Synchronise on audio track")
143 #define ASYNC_LONGTEXT N_( \
144 "This option will drop/duplicate video frames to synchronise the video " \
145 "track on the audio track." )
147 #define HURRYUP_TEXT N_( "Hurry up" )
148 #define HURRYUP_LONGTEXT N_( "The transcoder will drop frames if your CPU " \
149 "can't keep up with the encoding rate." )
151 static const char *const ppsz_deinterlace_type[] =
153 "deinterlace", "ffmpeg-deinterlace"
156 static int Open ( vlc_object_t * );
157 static void Close( vlc_object_t * );
159 #define SOUT_CFG_PREFIX "sout-transcode-"
162 set_shortname( N_("Transcode"))
163 set_description( N_("Transcode stream output") )
164 set_capability( "sout stream", 50 )
165 add_shortcut( "transcode" )
166 set_callbacks( Open, Close )
167 set_category( CAT_SOUT )
168 set_subcategory( SUBCAT_SOUT_STREAM )
169 set_section( N_("Video"), NULL )
170 add_string( SOUT_CFG_PREFIX "venc", NULL, NULL, VENC_TEXT,
171 VENC_LONGTEXT, false );
172 add_string( SOUT_CFG_PREFIX "vcodec", NULL, NULL, VCODEC_TEXT,
173 VCODEC_LONGTEXT, false );
174 add_integer( SOUT_CFG_PREFIX "vb", 800 * 1000, NULL, VB_TEXT,
175 VB_LONGTEXT, false );
176 add_float( SOUT_CFG_PREFIX "scale", 1, NULL, SCALE_TEXT,
177 SCALE_LONGTEXT, false );
178 add_float( SOUT_CFG_PREFIX "fps", 0, NULL, FPS_TEXT,
179 FPS_LONGTEXT, false );
180 add_bool( SOUT_CFG_PREFIX "hurry-up", true, NULL, HURRYUP_TEXT,
181 HURRYUP_LONGTEXT, false );
182 add_bool( SOUT_CFG_PREFIX "deinterlace", 0, NULL, DEINTERLACE_TEXT,
183 DEINTERLACE_LONGTEXT, false );
184 add_string( SOUT_CFG_PREFIX "deinterlace-module", "deinterlace", NULL,
185 DEINTERLACE_MODULE_TEXT, DEINTERLACE_MODULE_LONGTEXT,
187 change_string_list( ppsz_deinterlace_type, 0, 0 );
188 add_integer( SOUT_CFG_PREFIX "width", 0, NULL, WIDTH_TEXT,
189 WIDTH_LONGTEXT, true );
190 add_integer( SOUT_CFG_PREFIX "height", 0, NULL, HEIGHT_TEXT,
191 HEIGHT_LONGTEXT, true );
192 add_integer( SOUT_CFG_PREFIX "maxwidth", 0, NULL, MAXWIDTH_TEXT,
193 MAXWIDTH_LONGTEXT, true );
194 add_integer( SOUT_CFG_PREFIX "maxheight", 0, NULL, MAXHEIGHT_TEXT,
195 MAXHEIGHT_LONGTEXT, true );
196 add_module_list( SOUT_CFG_PREFIX "vfilter", "video filter2",
198 VFILTER_TEXT, VFILTER_LONGTEXT, false );
200 set_section( N_("Audio"), NULL )
201 add_string( SOUT_CFG_PREFIX "aenc", NULL, NULL, AENC_TEXT,
202 AENC_LONGTEXT, false );
203 add_string( SOUT_CFG_PREFIX "acodec", NULL, NULL, ACODEC_TEXT,
204 ACODEC_LONGTEXT, false );
205 add_integer( SOUT_CFG_PREFIX "ab", 0, NULL, AB_TEXT,
206 AB_LONGTEXT, false );
207 add_integer( SOUT_CFG_PREFIX "channels", 0, NULL, ACHANS_TEXT,
208 ACHANS_LONGTEXT, false );
209 add_integer( SOUT_CFG_PREFIX "samplerate", 0, NULL, ARATE_TEXT,
210 ARATE_LONGTEXT, true );
211 add_bool( SOUT_CFG_PREFIX "audio-sync", 0, NULL, ASYNC_TEXT,
212 ASYNC_LONGTEXT, false );
213 add_module_list( SOUT_CFG_PREFIX "afilter", "audio filter2",
215 AFILTER_TEXT, AFILTER_LONGTEXT, false );
217 set_section( N_("Overlays/Subtitles"), NULL )
218 add_string( SOUT_CFG_PREFIX "senc", NULL, NULL, SENC_TEXT,
219 SENC_LONGTEXT, false );
220 add_string( SOUT_CFG_PREFIX "scodec", NULL, NULL, SCODEC_TEXT,
221 SCODEC_LONGTEXT, false );
222 add_bool( SOUT_CFG_PREFIX "soverlay", 0, NULL, SCODEC_TEXT,
223 SCODEC_LONGTEXT, false );
224 add_module_list( SOUT_CFG_PREFIX "sfilter", "video filter",
226 SFILTER_TEXT, SFILTER_LONGTEXT, false );
228 set_section( N_("On Screen Display"), NULL )
229 add_bool( SOUT_CFG_PREFIX "osd", 0, NULL, OSD_TEXT,
230 OSD_LONGTEXT, false );
232 set_section( N_("Miscellaneous"), NULL )
233 add_integer( SOUT_CFG_PREFIX "threads", 0, NULL, THREADS_TEXT,
234 THREADS_LONGTEXT, true );
235 add_bool( SOUT_CFG_PREFIX "high-priority", 0, NULL, HP_TEXT, HP_LONGTEXT,
240 static const char *const ppsz_sout_options[] = {
241 "venc", "vcodec", "vb",
242 "scale", "fps", "width", "height", "vfilter", "deinterlace",
243 "deinterlace-module", "threads", "hurry-up", "aenc", "acodec", "ab",
244 "afilter", "samplerate", "channels", "senc", "scodec", "soverlay",
245 "sfilter", "osd", "audio-sync", "high-priority", "maxwidth", "maxheight",
249 /*****************************************************************************
250 * Exported prototypes
251 *****************************************************************************/
252 static sout_stream_id_t *Add ( sout_stream_t *, es_format_t * );
253 static int Del ( sout_stream_t *, sout_stream_id_t * );
254 static int Send( sout_stream_t *, sout_stream_id_t *, block_t* );
256 static int transcode_audio_new ( sout_stream_t *, sout_stream_id_t * );
257 static void transcode_audio_close ( sout_stream_id_t * );
258 static int transcode_audio_process( sout_stream_t *, sout_stream_id_t *,
259 block_t *, block_t ** );
261 static aout_buffer_t *audio_new_buffer( decoder_t *, int );
262 static void audio_del_buffer( decoder_t *, aout_buffer_t * );
264 static int transcode_video_new ( sout_stream_t *, sout_stream_id_t * );
265 static void transcode_video_close ( sout_stream_t *, sout_stream_id_t * );
266 static void transcode_video_encoder_init( sout_stream_t *, sout_stream_id_t *);
267 static int transcode_video_encoder_open( sout_stream_t *, sout_stream_id_t *);
268 static int transcode_video_process( sout_stream_t *, sout_stream_id_t *,
269 block_t *, block_t ** );
271 static void video_del_buffer( vlc_object_t *, picture_t * );
272 static picture_t *video_new_buffer_decoder( decoder_t * );
273 static void video_del_buffer_decoder( decoder_t *, picture_t * );
274 static void video_link_picture_decoder( decoder_t *, picture_t * );
275 static void video_unlink_picture_decoder( decoder_t *, picture_t * );
276 static picture_t *video_new_buffer_filter( filter_t * );
277 static void video_del_buffer_filter( filter_t *, picture_t * );
279 static int transcode_spu_new ( sout_stream_t *, sout_stream_id_t * );
280 static void transcode_spu_close ( sout_stream_id_t * );
281 static int transcode_spu_process( sout_stream_t *, sout_stream_id_t *,
282 block_t *, block_t ** );
284 static int transcode_osd_new ( sout_stream_t *, sout_stream_id_t * );
285 static void transcode_osd_close ( sout_stream_t *, sout_stream_id_t * );
286 static int transcode_osd_process( sout_stream_t *, sout_stream_id_t *,
287 block_t *, block_t ** );
289 static void* EncoderThread( vlc_object_t * p_this );
291 static const int pi_channels_maps[6] =
294 AOUT_CHAN_CENTER, AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
295 AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
296 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
297 | AOUT_CHAN_REARRIGHT,
298 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
299 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
302 #define PICTURE_RING_SIZE 64
303 #define SUBPICTURE_RING_SIZE 20
305 #define ENC_FRAMERATE (25 * 1000 + .5)
306 #define ENC_FRAMERATE_BASE 1000
308 struct sout_stream_sys_t
312 sout_stream_t *p_out;
313 sout_stream_id_t *id_video;
315 vlc_mutex_t lock_out;
317 picture_t * pp_pics[PICTURE_RING_SIZE];
318 int i_first_pic, i_last_pic;
321 vlc_fourcc_t i_acodec; /* codec audio (0 if not transcode) */
323 config_chain_t *p_audio_cfg;
324 uint32_t i_sample_rate;
331 vlc_fourcc_t i_vcodec; /* codec video (0 if not transcode) */
333 config_chain_t *p_video_cfg;
337 unsigned int i_width, i_maxwidth;
338 unsigned int i_height, i_maxheight;
340 char *psz_deinterlace;
341 config_chain_t *p_deinterlace_cfg;
343 bool b_high_priority;
349 vlc_fourcc_t i_scodec; /* codec spu (0 if not transcode) */
352 config_chain_t *p_spu_cfg;
356 vlc_fourcc_t i_osdcodec; /* codec osd menu (0 if not transcode) */
358 config_chain_t *p_osd_cfg;
359 bool b_osd; /* true when osd es is registered */
363 mtime_t i_master_drift;
366 struct decoder_owner_sys_t
368 picture_t *pp_pics[PICTURE_RING_SIZE];
369 sout_stream_sys_t *p_sys;
371 struct filter_owner_sys_t
373 picture_t *pp_pics[PICTURE_RING_SIZE];
374 sout_stream_sys_t *p_sys;
377 /*****************************************************************************
379 *****************************************************************************/
380 static int Open( vlc_object_t *p_this )
382 sout_stream_t *p_stream = (sout_stream_t*)p_this;
383 sout_stream_sys_t *p_sys;
386 p_sys = vlc_object_create( p_this, sizeof( sout_stream_sys_t ) );
388 p_sys->p_out = sout_StreamNew( p_stream->p_sout, p_stream->psz_next );
391 msg_Err( p_stream, "cannot create chain" );
392 vlc_object_release( p_sys );
396 p_sys->i_master_drift = 0;
398 config_ChainParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options,
401 /* Audio transcoding parameters */
402 var_Get( p_stream, SOUT_CFG_PREFIX "aenc", &val );
403 p_sys->psz_aenc = NULL;
404 p_sys->p_audio_cfg = NULL;
405 if( val.psz_string && *val.psz_string )
408 psz_next = config_ChainCreate( &p_sys->psz_aenc, &p_sys->p_audio_cfg,
412 free( val.psz_string );
414 var_Get( p_stream, SOUT_CFG_PREFIX "acodec", &val );
416 if( val.psz_string && *val.psz_string )
419 memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) );
420 p_sys->i_acodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
422 free( val.psz_string );
424 var_Get( p_stream, SOUT_CFG_PREFIX "ab", &val );
425 p_sys->i_abitrate = val.i_int;
426 if( p_sys->i_abitrate < 4000 ) p_sys->i_abitrate *= 1000;
428 var_Get( p_stream, SOUT_CFG_PREFIX "samplerate", &val );
429 p_sys->i_sample_rate = val.i_int;
431 var_Get( p_stream, SOUT_CFG_PREFIX "channels", &val );
432 p_sys->i_channels = val.i_int;
434 if( p_sys->i_acodec )
436 if( p_sys->i_acodec == VLC_FOURCC('m','p','3',0) &&
437 p_sys->i_channels > 2 )
439 msg_Warn( p_stream, "%d channels invalid for mp3, forcing to 2",
441 p_sys->i_channels = 2;
443 msg_Dbg( p_stream, "codec audio=%4.4s %dHz %d channels %dKb/s",
444 (char *)&p_sys->i_acodec, p_sys->i_sample_rate,
445 p_sys->i_channels, p_sys->i_abitrate / 1000 );
448 var_Get( p_stream, SOUT_CFG_PREFIX "afilter", &val );
449 if( val.psz_string && *val.psz_string )
450 p_sys->psz_af2 = val.psz_string;
453 free( val.psz_string );
454 p_sys->psz_af2 = NULL;
457 /* Video transcoding parameters */
458 var_Get( p_stream, SOUT_CFG_PREFIX "venc", &val );
459 p_sys->psz_venc = NULL;
460 p_sys->p_video_cfg = NULL;
461 if( val.psz_string && *val.psz_string )
464 psz_next = config_ChainCreate( &p_sys->psz_venc, &p_sys->p_video_cfg,
468 free( val.psz_string );
470 var_Get( p_stream, SOUT_CFG_PREFIX "vcodec", &val );
472 if( val.psz_string && *val.psz_string )
475 memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) );
476 p_sys->i_vcodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
478 free( val.psz_string );
480 var_Get( p_stream, SOUT_CFG_PREFIX "vb", &val );
481 p_sys->i_vbitrate = val.i_int;
482 if( p_sys->i_vbitrate < 16000 ) p_sys->i_vbitrate *= 1000;
484 var_Get( p_stream, SOUT_CFG_PREFIX "scale", &val );
485 p_sys->f_scale = val.f_float;
487 var_Get( p_stream, SOUT_CFG_PREFIX "fps", &val );
488 p_sys->f_fps = val.f_float;
490 var_Get( p_stream, SOUT_CFG_PREFIX "hurry-up", &val );
491 p_sys->b_hurry_up = val.b_bool;
493 var_Get( p_stream, SOUT_CFG_PREFIX "width", &val );
494 p_sys->i_width = val.i_int;
496 var_Get( p_stream, SOUT_CFG_PREFIX "height", &val );
497 p_sys->i_height = val.i_int;
499 var_Get( p_stream, SOUT_CFG_PREFIX "maxwidth", &val );
500 p_sys->i_maxwidth = val.i_int;
502 var_Get( p_stream, SOUT_CFG_PREFIX "maxheight", &val );
503 p_sys->i_maxheight = val.i_int;
505 var_Get( p_stream, SOUT_CFG_PREFIX "vfilter", &val );
506 if( val.psz_string && *val.psz_string )
507 p_sys->psz_vf2 = val.psz_string;
510 free( val.psz_string );
511 p_sys->psz_vf2 = NULL;
514 var_Get( p_stream, SOUT_CFG_PREFIX "deinterlace", &val );
515 p_sys->b_deinterlace = val.b_bool;
517 var_Get( p_stream, SOUT_CFG_PREFIX "deinterlace-module", &val );
518 p_sys->psz_deinterlace = NULL;
519 p_sys->p_deinterlace_cfg = NULL;
520 if( val.psz_string && *val.psz_string )
523 psz_next = config_ChainCreate( &p_sys->psz_deinterlace,
524 &p_sys->p_deinterlace_cfg,
528 free( val.psz_string );
530 var_Get( p_stream, SOUT_CFG_PREFIX "threads", &val );
531 p_sys->i_threads = val.i_int;
532 var_Get( p_stream, SOUT_CFG_PREFIX "high-priority", &val );
533 p_sys->b_high_priority = val.b_bool;
535 if( p_sys->i_vcodec )
537 msg_Dbg( p_stream, "codec video=%4.4s %dx%d scaling: %f %dkb/s",
538 (char *)&p_sys->i_vcodec, p_sys->i_width, p_sys->i_height,
539 p_sys->f_scale, p_sys->i_vbitrate / 1000 );
542 /* Subpictures transcoding parameters */
544 p_sys->psz_senc = NULL;
545 p_sys->p_spu_cfg = NULL;
548 var_Get( p_stream, SOUT_CFG_PREFIX "senc", &val );
549 if( val.psz_string && *val.psz_string )
552 psz_next = config_ChainCreate( &p_sys->psz_senc, &p_sys->p_spu_cfg,
556 free( val.psz_string );
558 var_Get( p_stream, SOUT_CFG_PREFIX "scodec", &val );
559 if( val.psz_string && *val.psz_string )
562 memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) );
563 p_sys->i_scodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
565 free( val.psz_string );
567 if( p_sys->i_scodec )
569 msg_Dbg( p_stream, "codec spu=%4.4s", (char *)&p_sys->i_scodec );
572 var_Get( p_stream, SOUT_CFG_PREFIX "soverlay", &val );
573 p_sys->b_soverlay = val.b_bool;
575 var_Get( p_stream, SOUT_CFG_PREFIX "sfilter", &val );
576 if( val.psz_string && *val.psz_string )
578 p_sys->p_spu = spu_Create( p_stream );
579 var_Create( p_sys->p_spu, "sub-filter", VLC_VAR_STRING );
580 var_Set( p_sys->p_spu, "sub-filter", val );
581 spu_Init( p_sys->p_spu );
583 free( val.psz_string );
585 /* OSD menu transcoding parameters */
586 p_sys->psz_osdenc = NULL;
587 p_sys->p_osd_cfg = NULL;
588 p_sys->i_osdcodec = 0;
589 p_sys->b_osd = false;
591 var_Get( p_stream, SOUT_CFG_PREFIX "osd", &val );
597 psz_next = config_ChainCreate( &p_sys->psz_osdenc,
598 &p_sys->p_osd_cfg, strdup( "dvbsub") );
601 p_sys->i_osdcodec = VLC_FOURCC('Y','U','V','P' );
603 msg_Dbg( p_stream, "codec osd=%4.4s", (char *)&p_sys->i_osdcodec );
607 osd_val.psz_string = strdup("osdmenu");
608 p_sys->p_spu = spu_Create( p_stream );
609 var_Create( p_sys->p_spu, "sub-filter", VLC_VAR_STRING );
610 var_Set( p_sys->p_spu, "sub-filter", osd_val );
611 spu_Init( p_sys->p_spu );
612 free( osd_val.psz_string );
616 osd_val.psz_string = strdup("osdmenu");
617 var_Set( p_sys->p_spu, "sub-filter", osd_val );
618 free( osd_val.psz_string );
623 var_Get( p_stream, SOUT_CFG_PREFIX "audio-sync", &val );
624 p_sys->b_master_sync = val.b_bool;
625 if( p_sys->f_fps > 0 ) p_sys->b_master_sync = true;
627 p_stream->pf_add = Add;
628 p_stream->pf_del = Del;
629 p_stream->pf_send = Send;
630 p_stream->p_sys = p_sys;
635 /*****************************************************************************
637 *****************************************************************************/
638 static void Close( vlc_object_t * p_this )
640 sout_stream_t *p_stream = (sout_stream_t*)p_this;
641 sout_stream_sys_t *p_sys = p_stream->p_sys;
643 sout_StreamDelete( p_sys->p_out );
645 free( p_sys->psz_af2 );
647 config_ChainDestroy( p_sys->p_audio_cfg );
648 free( p_sys->psz_aenc );
650 free( p_sys->psz_vf2 );
652 config_ChainDestroy( p_sys->p_video_cfg );
653 free( p_sys->psz_venc );
655 config_ChainDestroy( p_sys->p_deinterlace_cfg );
656 free( p_sys->psz_deinterlace );
658 config_ChainDestroy( p_sys->p_spu_cfg );
659 free( p_sys->psz_senc );
661 if( p_sys->p_spu ) spu_Destroy( p_sys->p_spu );
663 config_ChainDestroy( p_sys->p_osd_cfg );
664 free( p_sys->psz_osdenc );
666 vlc_object_release( p_sys );
669 struct sout_stream_id_t
673 /* id of the out stream */
677 decoder_t *p_decoder;
680 filter_chain_t *p_f_chain;
681 /* User specified filters */
682 filter_chain_t *p_uf_chain;
685 encoder_t *p_encoder;
688 date_t interpolated_pts;
691 static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
693 sout_stream_sys_t *p_sys = p_stream->p_sys;
694 sout_stream_id_t *id;
696 id = calloc( 1, 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", false );
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;
1278 if( id->p_decoder->p_description )
1279 vlc_meta_Delete( id->p_decoder->p_description );
1280 id->p_decoder->p_description = NULL;
1283 if( id->p_encoder->p_module )
1284 module_unneed( id->p_encoder, id->p_encoder->p_module );
1285 id->p_encoder->p_module = NULL;
1289 filter_chain_Delete( id->p_f_chain );
1290 if( id->p_uf_chain )
1291 filter_chain_Delete( id->p_uf_chain );
1294 static int transcode_audio_process( sout_stream_t *p_stream,
1295 sout_stream_id_t *id,
1296 block_t *in, block_t **out )
1298 sout_stream_sys_t *p_sys = p_stream->p_sys;
1299 aout_buffer_t *p_audio_buf;
1300 block_t *p_block, *p_audio_block;
1303 while( (p_audio_buf = id->p_decoder->pf_decode_audio( id->p_decoder,
1306 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_AUDIO, 1 );
1307 if( p_sys->b_master_sync )
1309 mtime_t i_dts = date_Get( &id->interpolated_pts ) + 1;
1310 if ( p_audio_buf->start_date - i_dts > MASTER_SYNC_MAX_DRIFT
1311 || p_audio_buf->start_date - i_dts < -MASTER_SYNC_MAX_DRIFT )
1313 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1314 date_Set( &id->interpolated_pts, p_audio_buf->start_date );
1315 i_dts = p_audio_buf->start_date + 1;
1317 p_sys->i_master_drift = p_audio_buf->start_date - i_dts;
1318 date_Increment( &id->interpolated_pts, p_audio_buf->i_nb_samples );
1319 p_audio_buf->start_date -= p_sys->i_master_drift;
1320 p_audio_buf->end_date -= p_sys->i_master_drift;
1323 p_audio_block = p_audio_buf->p_sys;
1324 p_audio_block->i_buffer = p_audio_buf->i_nb_bytes;
1325 p_audio_block->i_dts = p_audio_block->i_pts =
1326 p_audio_buf->start_date;
1327 p_audio_block->i_length = p_audio_buf->end_date -
1328 p_audio_buf->start_date;
1329 p_audio_block->i_samples = p_audio_buf->i_nb_samples;
1331 /* Run filter chain */
1332 p_audio_block = filter_chain_AudioFilter( id->p_f_chain, p_audio_block );
1333 if( id->p_uf_chain )
1334 p_audio_block = filter_chain_AudioFilter( id->p_uf_chain, p_audio_block );
1335 assert( p_audio_block );
1337 p_audio_buf->p_buffer = p_audio_block->p_buffer;
1338 p_audio_buf->i_nb_bytes = p_audio_block->i_buffer;
1339 p_audio_buf->i_nb_samples = p_audio_block->i_samples;
1340 p_audio_buf->start_date = p_audio_block->i_dts;
1341 p_audio_buf->end_date = p_audio_block->i_dts + p_audio_block->i_length;
1343 audio_timer_start( id->p_encoder );
1344 p_block = id->p_encoder->pf_encode_audio( id->p_encoder, p_audio_buf );
1345 audio_timer_stop( id->p_encoder );
1347 block_ChainAppend( out, p_block );
1348 block_Release( p_audio_block );
1349 free( p_audio_buf );
1355 static void audio_release_buffer( aout_buffer_t *p_buffer )
1357 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1361 static aout_buffer_t *audio_new_buffer( decoder_t *p_dec, int i_samples )
1363 aout_buffer_t *p_buffer;
1367 if( p_dec->fmt_out.audio.i_bitspersample )
1369 i_size = i_samples * p_dec->fmt_out.audio.i_bitspersample / 8 *
1370 p_dec->fmt_out.audio.i_channels;
1372 else if( p_dec->fmt_out.audio.i_bytes_per_frame &&
1373 p_dec->fmt_out.audio.i_frame_length )
1375 i_size = i_samples * p_dec->fmt_out.audio.i_bytes_per_frame /
1376 p_dec->fmt_out.audio.i_frame_length;
1380 i_size = i_samples * 4 * p_dec->fmt_out.audio.i_channels;
1383 p_buffer = malloc( sizeof(aout_buffer_t) );
1384 if( !p_buffer ) return NULL;
1385 p_buffer->b_discontinuity = false;
1386 p_buffer->pf_release = audio_release_buffer;
1387 p_buffer->p_sys = p_block = block_New( p_dec, i_size );
1389 p_buffer->p_buffer = p_block->p_buffer;
1390 p_buffer->i_size = p_buffer->i_nb_bytes = p_block->i_buffer;
1391 p_buffer->i_nb_samples = i_samples;
1392 p_block->i_samples = i_samples;
1397 static void audio_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
1400 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1408 static int transcode_video_filter_allocation_init( filter_t *p_filter,
1411 sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_data;
1414 p_filter->pf_vout_buffer_new = video_new_buffer_filter;
1415 p_filter->pf_vout_buffer_del = video_del_buffer_filter;
1417 p_filter->p_owner = malloc( sizeof(filter_owner_sys_t) );
1418 if( !p_filter->p_owner )
1419 return VLC_EGENERIC;
1421 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1422 p_filter->p_owner->pp_pics[i] = 0;
1423 p_filter->p_owner->p_sys = p_sys;
1428 static void transcode_video_filter_allocation_clear( filter_t *p_filter )
1432 /* Clean-up pictures ring buffer */
1433 for( j = 0; j < PICTURE_RING_SIZE; j++ )
1435 if( p_filter->p_owner->pp_pics[j] )
1436 video_del_buffer( VLC_OBJECT(p_filter),
1437 p_filter->p_owner->pp_pics[j] );
1439 free( p_filter->p_owner );
1442 static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
1444 sout_stream_sys_t *p_sys = p_stream->p_sys;
1448 * Initialization of decoder structures
1450 id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1451 id->p_decoder->fmt_out.i_extra = 0;
1452 id->p_decoder->fmt_out.p_extra = 0;
1453 id->p_decoder->pf_decode_video = NULL;
1454 id->p_decoder->pf_get_cc = NULL;
1455 id->p_decoder->pf_get_cc = 0;
1456 id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
1457 id->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder;
1458 id->p_decoder->pf_picture_link = video_link_picture_decoder;
1459 id->p_decoder->pf_picture_unlink = video_unlink_picture_decoder;
1460 id->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) );
1461 if( !id->p_decoder->p_owner )
1462 return VLC_EGENERIC;
1464 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1465 id->p_decoder->p_owner->pp_pics[i] = 0;
1466 id->p_decoder->p_owner->p_sys = p_sys;
1467 /* id->p_decoder->p_cfg = p_sys->p_video_cfg; */
1469 id->p_decoder->p_module =
1470 module_need( id->p_decoder, "decoder", "$codec", false );
1472 if( !id->p_decoder->p_module )
1474 msg_Err( p_stream, "cannot find video decoder" );
1475 free( id->p_decoder->p_owner );
1476 return VLC_EGENERIC;
1481 * Because some info about the decoded input will only be available
1482 * once the first frame is decoded, we actually only test the availability
1483 * of the encoder here.
1486 /* Initialization of encoder format structures */
1487 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1488 id->p_decoder->fmt_out.i_codec );
1489 id->p_encoder->fmt_in.video.i_chroma = id->p_decoder->fmt_out.i_codec;
1491 /* The dimensions will be set properly later on.
1492 * Just put sensible values so we can test an encoder is available. */
1493 id->p_encoder->fmt_in.video.i_width =
1494 id->p_encoder->fmt_out.video.i_width ?:
1495 id->p_decoder->fmt_in.video.i_width ?: 16;
1496 id->p_encoder->fmt_in.video.i_height =
1497 id->p_encoder->fmt_out.video.i_height ?:
1498 id->p_decoder->fmt_in.video.i_height ?: 16;
1499 id->p_encoder->fmt_in.video.i_frame_rate = ENC_FRAMERATE;
1500 id->p_encoder->fmt_in.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1502 id->p_encoder->i_threads = p_sys->i_threads;
1503 id->p_encoder->p_cfg = p_sys->p_video_cfg;
1505 id->p_encoder->p_module =
1506 module_need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1507 if( !id->p_encoder->p_module )
1509 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1510 p_sys->psz_venc ? p_sys->psz_venc : "any",
1511 (char *)&p_sys->i_vcodec );
1512 module_unneed( id->p_decoder, id->p_decoder->p_module );
1513 id->p_decoder->p_module = 0;
1514 free( id->p_decoder->p_owner );
1515 return VLC_EGENERIC;
1518 /* Close the encoder.
1519 * We'll open it only when we have the first frame. */
1520 module_unneed( id->p_encoder, id->p_encoder->p_module );
1521 if( id->p_encoder->fmt_out.p_extra )
1523 free( id->p_encoder->fmt_out.p_extra );
1524 id->p_encoder->fmt_out.p_extra = NULL;
1525 id->p_encoder->fmt_out.i_extra = 0;
1527 id->p_encoder->p_module = NULL;
1529 if( p_sys->i_threads >= 1 )
1531 int i_priority = p_sys->b_high_priority ? VLC_THREAD_PRIORITY_OUTPUT :
1532 VLC_THREAD_PRIORITY_VIDEO;
1533 p_sys->id_video = id;
1534 vlc_mutex_init( &p_sys->lock_out );
1535 vlc_cond_init( &p_sys->cond );
1536 memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) );
1537 p_sys->i_first_pic = 0;
1538 p_sys->i_last_pic = 0;
1539 p_sys->p_buffers = NULL;
1540 p_sys->b_die = p_sys->b_error = 0;
1541 if( vlc_thread_create( p_sys, "encoder", EncoderThread, i_priority,
1544 msg_Err( p_stream, "cannot spawn encoder thread" );
1545 module_unneed( id->p_decoder, id->p_decoder->p_module );
1546 id->p_decoder->p_module = 0;
1547 free( id->p_decoder->p_owner );
1548 return VLC_EGENERIC;
1555 static void transcode_video_encoder_init( sout_stream_t *p_stream,
1556 sout_stream_id_t *id )
1558 sout_stream_sys_t *p_sys = p_stream->p_sys;
1560 /* Calculate scaling
1561 * width/height of source */
1562 int i_src_width = id->p_decoder->fmt_out.video.i_width;
1563 int i_src_height = id->p_decoder->fmt_out.video.i_height;
1565 /* with/height scaling */
1566 float f_scale_width = 1;
1567 float f_scale_height = 1;
1569 /* width/height of output stream */
1574 float f_aspect = (float)id->p_decoder->fmt_out.video.i_aspect /
1577 msg_Dbg( p_stream, "decoder aspect is %i:%i",
1578 id->p_decoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1580 /* Change f_aspect from source frame to source pixel */
1581 f_aspect = f_aspect * i_src_height / i_src_width;
1582 msg_Dbg( p_stream, "source pixel aspect is %f:1", f_aspect );
1584 /* Calculate scaling factor for specified parameters */
1585 if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1586 id->p_encoder->fmt_out.video.i_height <= 0 && p_sys->f_scale )
1588 /* Global scaling. Make sure width will remain a factor of 16 */
1591 int i_new_width = i_src_width * p_sys->f_scale;
1593 if( i_new_width % 16 <= 7 && i_new_width >= 16 )
1594 i_new_width -= i_new_width % 16;
1596 i_new_width += 16 - i_new_width % 16;
1598 f_real_scale = (float)( i_new_width ) / (float) i_src_width;
1600 i_new_height = __MAX( 16, i_src_height * (float)f_real_scale );
1602 f_scale_width = f_real_scale;
1603 f_scale_height = (float) i_new_height / (float) i_src_height;
1605 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1606 id->p_encoder->fmt_out.video.i_height <= 0 )
1608 /* Only width specified */
1609 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1610 f_scale_height = f_scale_width;
1612 else if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1613 id->p_encoder->fmt_out.video.i_height > 0 )
1615 /* Only height specified */
1616 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1617 f_scale_width = f_scale_height;
1619 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1620 id->p_encoder->fmt_out.video.i_height > 0 )
1622 /* Width and height specified */
1623 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1624 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1627 /* check maxwidth and maxheight
1629 if( p_sys->i_maxwidth && f_scale_width > (float)p_sys->i_maxwidth /
1632 f_scale_width = (float)p_sys->i_maxwidth / i_src_width;
1635 if( p_sys->i_maxheight && f_scale_height > (float)p_sys->i_maxheight /
1638 f_scale_height = (float)p_sys->i_maxheight / i_src_height;
1642 /* Change aspect ratio from source pixel to scaled pixel */
1643 f_aspect = f_aspect * f_scale_height / f_scale_width;
1644 msg_Dbg( p_stream, "scaled pixel aspect is %f:1", f_aspect );
1646 /* f_scale_width and f_scale_height are now final */
1647 /* Calculate width, height from scaling
1648 * Make sure its multiple of 2
1650 i_dst_width = 2 * (int)(f_scale_width*i_src_width/2+0.5);
1651 i_dst_height = 2 * (int)(f_scale_height*i_src_height/2+0.5);
1653 /* Change aspect ratio from scaled pixel to output frame */
1654 f_aspect = f_aspect * i_dst_width / i_dst_height;
1656 /* Store calculated values */
1657 id->p_encoder->fmt_out.video.i_width =
1658 id->p_encoder->fmt_out.video.i_visible_width = i_dst_width;
1659 id->p_encoder->fmt_out.video.i_height =
1660 id->p_encoder->fmt_out.video.i_visible_height = i_dst_height;
1662 id->p_encoder->fmt_in.video.i_width =
1663 id->p_encoder->fmt_in.video.i_visible_width = i_dst_width;
1664 id->p_encoder->fmt_in.video.i_height =
1665 id->p_encoder->fmt_in.video.i_visible_height = i_dst_height;
1667 msg_Dbg( p_stream, "source %ix%i, destination %ix%i",
1668 i_src_width, i_src_height,
1669 i_dst_width, i_dst_height
1672 /* Handle frame rate conversion */
1673 if( !id->p_encoder->fmt_out.video.i_frame_rate ||
1674 !id->p_encoder->fmt_out.video.i_frame_rate_base )
1676 if( id->p_decoder->fmt_out.video.i_frame_rate &&
1677 id->p_decoder->fmt_out.video.i_frame_rate_base )
1679 id->p_encoder->fmt_out.video.i_frame_rate =
1680 id->p_decoder->fmt_out.video.i_frame_rate;
1681 id->p_encoder->fmt_out.video.i_frame_rate_base =
1682 id->p_decoder->fmt_out.video.i_frame_rate_base;
1686 /* Pick a sensible default value */
1687 id->p_encoder->fmt_out.video.i_frame_rate = ENC_FRAMERATE;
1688 id->p_encoder->fmt_out.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1692 id->p_encoder->fmt_in.video.i_frame_rate =
1693 id->p_encoder->fmt_out.video.i_frame_rate;
1694 id->p_encoder->fmt_in.video.i_frame_rate_base =
1695 id->p_encoder->fmt_out.video.i_frame_rate_base;
1697 date_Init( &id->interpolated_pts,
1698 id->p_encoder->fmt_out.video.i_frame_rate,
1699 id->p_encoder->fmt_out.video.i_frame_rate_base );
1701 /* Check whether a particular aspect ratio was requested */
1702 if( !id->p_encoder->fmt_out.video.i_aspect )
1704 id->p_encoder->fmt_out.video.i_aspect =
1705 (int)( f_aspect * VOUT_ASPECT_FACTOR + 0.5 );
1707 id->p_encoder->fmt_in.video.i_aspect =
1708 id->p_encoder->fmt_out.video.i_aspect;
1710 msg_Dbg( p_stream, "encoder aspect is %i:%i",
1711 id->p_encoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1713 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1716 static int transcode_video_encoder_open( sout_stream_t *p_stream,
1717 sout_stream_id_t *id )
1719 sout_stream_sys_t *p_sys = p_stream->p_sys;
1722 msg_Dbg( p_stream, "destination (after video filters) %ix%i",
1723 id->p_encoder->fmt_in.video.i_width,
1724 id->p_encoder->fmt_in.video.i_height );
1726 id->p_encoder->p_module =
1727 module_need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1728 if( !id->p_encoder->p_module )
1730 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1731 p_sys->psz_venc ? p_sys->psz_venc : "any",
1732 (char *)&p_sys->i_vcodec );
1733 return VLC_EGENERIC;
1736 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1738 /* Hack for mp2v/mp1v transcoding support */
1739 if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','1','v') ||
1740 id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','2','v') )
1742 id->p_encoder->fmt_out.i_codec = VLC_FOURCC('m','p','g','v');
1745 id->id = sout_StreamIdAdd( p_stream->p_sys->p_out,
1746 &id->p_encoder->fmt_out );
1749 msg_Err( p_stream, "cannot add this stream" );
1750 return VLC_EGENERIC;
1756 static void transcode_video_close( sout_stream_t *p_stream,
1757 sout_stream_id_t *id )
1761 if( p_stream->p_sys->i_threads >= 1 )
1763 vlc_mutex_lock( &p_stream->p_sys->lock_out );
1764 vlc_object_kill( p_stream->p_sys );
1765 vlc_cond_signal( &p_stream->p_sys->cond );
1766 vlc_mutex_unlock( &p_stream->p_sys->lock_out );
1767 vlc_thread_join( p_stream->p_sys );
1768 vlc_mutex_destroy( &p_stream->p_sys->lock_out );
1769 vlc_cond_destroy( &p_stream->p_sys->cond );
1772 video_timer_close( id->p_encoder );
1775 if( id->p_decoder->p_module )
1776 module_unneed( id->p_decoder, id->p_decoder->p_module );
1777 if( id->p_decoder->p_description )
1778 vlc_meta_Delete( id->p_decoder->p_description );
1780 if( id->p_decoder->p_owner )
1782 /* Clean-up pictures ring buffer */
1783 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1785 if( id->p_decoder->p_owner->pp_pics[i] )
1786 video_del_buffer( VLC_OBJECT(id->p_decoder),
1787 id->p_decoder->p_owner->pp_pics[i] );
1789 free( id->p_decoder->p_owner );
1793 if( id->p_encoder->p_module )
1794 module_unneed( id->p_encoder, id->p_encoder->p_module );
1798 filter_chain_Delete( id->p_f_chain );
1799 if( id->p_uf_chain )
1800 filter_chain_Delete( id->p_uf_chain );
1803 static int transcode_video_process( sout_stream_t *p_stream,
1804 sout_stream_id_t *id,
1805 block_t *in, block_t **out )
1807 sout_stream_sys_t *p_sys = p_stream->p_sys;
1808 int i_duplicate = 1;
1809 picture_t *p_pic, *p_pic2 = NULL;
1812 while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
1814 subpicture_t *p_subpic = NULL;
1816 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_VIDEO, 1 );
1818 if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )
1820 mtime_t current_date = mdate();
1821 if( current_date + 50000 > p_pic->date )
1823 msg_Dbg( p_stream, "late picture skipped (%"PRId64")",
1824 current_date + 50000 - p_pic->date );
1825 p_pic->pf_release( p_pic );
1830 if( p_sys->b_master_sync )
1832 mtime_t i_video_drift;
1833 mtime_t i_master_drift = p_sys->i_master_drift;
1836 i_pts = date_Get( &id->interpolated_pts ) + 1;
1837 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1838 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
1840 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1841 date_Set( &id->interpolated_pts, p_pic->date );
1842 i_pts = p_pic->date + 1;
1844 i_video_drift = p_pic->date - i_pts;
1847 /* Set the pts of the frame being encoded */
1848 p_pic->date = i_pts;
1850 if( i_video_drift < (i_master_drift - 50000) )
1853 msg_Dbg( p_stream, "dropping frame (%i)",
1854 (int)(i_video_drift - i_master_drift) );
1856 p_pic->pf_release( p_pic );
1859 else if( i_video_drift > (i_master_drift + 50000) )
1862 msg_Dbg( p_stream, "adding frame (%i)",
1863 (int)(i_video_drift - i_master_drift) );
1869 if( !id->p_encoder->p_module )
1871 transcode_video_encoder_init( p_stream, id );
1873 id->p_f_chain = filter_chain_New( p_stream, "video filter2",
1875 transcode_video_filter_allocation_init,
1876 transcode_video_filter_allocation_clear,
1880 if( p_stream->p_sys->b_deinterlace )
1882 filter_chain_AppendFilter( id->p_f_chain,
1883 p_sys->psz_deinterlace,
1884 p_sys->p_deinterlace_cfg,
1885 &id->p_decoder->fmt_out,
1886 &id->p_decoder->fmt_out );
1889 /* Take care of the scaling and chroma conversions */
1890 if( ( id->p_decoder->fmt_out.video.i_chroma !=
1891 id->p_encoder->fmt_in.video.i_chroma ) ||
1892 ( id->p_decoder->fmt_out.video.i_width !=
1893 id->p_encoder->fmt_in.video.i_width ) ||
1894 ( id->p_decoder->fmt_out.video.i_height !=
1895 id->p_encoder->fmt_in.video.i_height ) )
1897 filter_chain_AppendFilter( id->p_f_chain,
1899 &id->p_decoder->fmt_out,
1900 &id->p_encoder->fmt_in );
1903 if( p_sys->psz_vf2 )
1905 const es_format_t *p_fmt_out;
1906 id->p_uf_chain = filter_chain_New( p_stream, "video filter2",
1908 transcode_video_filter_allocation_init,
1909 transcode_video_filter_allocation_clear,
1911 filter_chain_Reset( id->p_uf_chain, &id->p_encoder->fmt_in,
1912 &id->p_encoder->fmt_in );
1913 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_vf2 );
1914 p_fmt_out = filter_chain_GetFmtOut( id->p_uf_chain );
1915 es_format_Copy( &id->p_encoder->fmt_in, p_fmt_out );
1916 id->p_encoder->fmt_out.video.i_width =
1917 id->p_encoder->fmt_in.video.i_width;
1918 id->p_encoder->fmt_out.video.i_height =
1919 id->p_encoder->fmt_in.video.i_height;
1920 id->p_encoder->fmt_out.video.i_aspect =
1921 id->p_encoder->fmt_in.video.i_aspect;
1924 if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS )
1926 p_pic->pf_release( p_pic );
1927 transcode_video_close( p_stream, id );
1928 id->b_transcode = false;
1929 return VLC_EGENERIC;
1933 /* Run filter chain */
1935 p_pic = filter_chain_VideoFilter( id->p_f_chain, p_pic );
1941 /* Check if we have a subpicture to overlay */
1944 p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date,
1945 false /* Fixme: check if stream is paused */, false );
1946 /* TODO: get another pic */
1949 /* Overlay subpicture */
1954 if( p_pic->i_refcount && !filter_chain_GetLength( id->p_f_chain ) )
1956 /* We can't modify the picture, we need to duplicate it */
1957 picture_t *p_tmp = video_new_buffer_decoder( id->p_decoder );
1960 picture_Copy( p_tmp, p_pic );
1961 p_pic->pf_release( p_pic );
1966 if( filter_chain_GetLength( id->p_f_chain ) > 0 )
1967 fmt = filter_chain_GetFmtOut( id->p_f_chain )->video;
1969 fmt = id->p_decoder->fmt_out.video;
1971 /* FIXME (shouldn't have to be done here) */
1972 fmt.i_sar_num = fmt.i_aspect * fmt.i_height / fmt.i_width;
1973 fmt.i_sar_den = VOUT_ASPECT_FACTOR;
1975 spu_RenderSubpictures( p_sys->p_spu, p_pic, &fmt,
1976 p_subpic, &id->p_decoder->fmt_out.video, false );
1979 /* Run user specified filter chain */
1980 if( id->p_uf_chain )
1981 p_pic = filter_chain_VideoFilter( id->p_uf_chain, p_pic );
1983 if( p_sys->i_threads == 0 )
1987 video_timer_start( id->p_encoder );
1988 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
1989 video_timer_stop( id->p_encoder );
1991 block_ChainAppend( out, p_block );
1994 if( p_sys->b_master_sync )
1996 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
1997 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1998 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
2000 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2001 date_Set( &id->interpolated_pts, p_pic->date );
2002 i_pts = p_pic->date + 1;
2004 date_Increment( &id->interpolated_pts, 1 );
2007 if( p_sys->b_master_sync && i_duplicate > 1 )
2009 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
2010 if( (p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT)
2011 || ((p_pic->date - i_pts) < -MASTER_SYNC_MAX_DRIFT) )
2013 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2014 date_Set( &id->interpolated_pts, p_pic->date );
2015 i_pts = p_pic->date + 1;
2017 date_Increment( &id->interpolated_pts, 1 );
2019 if( p_sys->i_threads >= 1 )
2021 /* We can't modify the picture, we need to duplicate it */
2022 p_pic2 = video_new_buffer_decoder( id->p_decoder );
2023 if( p_pic2 != NULL )
2025 picture_Copy( p_pic2, p_pic );
2026 p_pic2->date = i_pts;
2032 p_pic->date = i_pts;
2033 video_timer_start( id->p_encoder );
2034 p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);
2035 video_timer_stop( id->p_encoder );
2036 block_ChainAppend( out, p_block );
2040 if( p_sys->i_threads == 0 )
2042 p_pic->pf_release( p_pic );
2046 vlc_mutex_lock( &p_sys->lock_out );
2047 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
2048 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2049 *out = p_sys->p_buffers;
2050 p_sys->p_buffers = NULL;
2051 if( p_pic2 != NULL )
2053 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic2;
2054 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2056 vlc_cond_signal( &p_sys->cond );
2057 vlc_mutex_unlock( &p_sys->lock_out );
2064 static void* EncoderThread( vlc_object_t* p_this )
2066 sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_this;
2067 sout_stream_id_t *id = p_sys->id_video;
2069 int canc = vlc_savecancel ();
2071 while( vlc_object_alive (p_sys) && !p_sys->b_error )
2075 vlc_mutex_lock( &p_sys->lock_out );
2076 while( p_sys->i_last_pic == p_sys->i_first_pic )
2078 vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );
2079 if( !vlc_object_alive (p_sys) || p_sys->b_error ) break;
2081 if( !vlc_object_alive (p_sys) || p_sys->b_error )
2083 vlc_mutex_unlock( &p_sys->lock_out );
2087 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2088 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2089 vlc_mutex_unlock( &p_sys->lock_out );
2091 video_timer_start( id->p_encoder );
2092 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2093 video_timer_stop( id->p_encoder );
2095 vlc_mutex_lock( &p_sys->lock_out );
2096 block_ChainAppend( &p_sys->p_buffers, p_block );
2098 vlc_mutex_unlock( &p_sys->lock_out );
2099 p_pic->pf_release( p_pic );
2102 while( p_sys->i_last_pic != p_sys->i_first_pic )
2104 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2105 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2106 p_pic->pf_release( p_pic );
2108 block_ChainRelease( p_sys->p_buffers );
2110 vlc_restorecancel (canc);
2114 struct picture_sys_t
2116 vlc_object_t *p_owner;
2119 static void video_release_buffer( picture_t *p_pic )
2121 if( p_pic && !p_pic->i_refcount && p_pic->pf_release && p_pic->p_sys )
2123 video_del_buffer_decoder( (decoder_t *)p_pic->p_sys->p_owner, p_pic );
2125 else if( p_pic && p_pic->i_refcount > 0 ) p_pic->i_refcount--;
2128 static picture_t *video_new_buffer( vlc_object_t *p_this, picture_t **pp_ring,
2129 sout_stream_sys_t *p_sys )
2131 decoder_t *p_dec = (decoder_t *)p_this;
2135 /* Find an empty space in the picture ring buffer */
2136 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2138 if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2140 pp_ring[i]->i_status = RESERVED_PICTURE;
2144 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2146 if( pp_ring[i] == 0 ) break;
2149 if( i == PICTURE_RING_SIZE && p_sys->i_threads >= 1 )
2151 int i_first_pic = p_sys->i_first_pic;
2153 if( p_sys->i_first_pic != p_sys->i_last_pic )
2155 /* Encoder still has stuff to encode, wait to clear-up the list */
2156 while( p_sys->i_first_pic == i_first_pic )
2160 /* Find an empty space in the picture ring buffer */
2161 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2163 if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2165 pp_ring[i]->i_status = RESERVED_PICTURE;
2169 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2171 if( pp_ring[i] == 0 ) break;
2175 if( i == PICTURE_RING_SIZE )
2177 msg_Err( p_this, "decoder/filter is leaking pictures, "
2178 "resetting its ring buffer" );
2180 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2182 pp_ring[i]->pf_release( pp_ring[i] );
2188 p_pic = picture_New( p_dec->fmt_out.video.i_chroma,
2189 p_dec->fmt_out.video.i_width,
2190 p_dec->fmt_out.video.i_height,
2191 p_dec->fmt_out.video.i_aspect );
2192 if( !p_pic ) return NULL;
2193 p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
2194 p_pic->p_sys = calloc( 1, sizeof(picture_sys_t) );
2197 picture_Release( p_pic );
2200 p_pic->pf_release = video_release_buffer;
2201 p_pic->i_refcount = 0;
2207 static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
2209 return video_new_buffer( VLC_OBJECT(p_dec),
2210 p_dec->p_owner->pp_pics, p_dec->p_owner->p_sys );
2213 static picture_t *video_new_buffer_filter( filter_t *p_filter )
2215 return video_new_buffer( VLC_OBJECT(p_filter),
2216 p_filter->p_owner->pp_pics,
2217 p_filter->p_owner->p_sys );
2220 static void video_del_buffer( vlc_object_t *p_this, picture_t *p_pic )
2226 free( p_pic->p_data_orig );
2227 free( p_pic->p_sys );
2232 static void video_del_buffer_decoder( decoder_t *p_decoder, picture_t *p_pic )
2234 VLC_UNUSED(p_decoder);
2235 p_pic->i_refcount = 0;
2236 p_pic->i_status = DESTROYED_PICTURE;
2237 picture_CleanupQuant( p_pic );
2240 static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic )
2242 VLC_UNUSED(p_filter);
2243 p_pic->i_refcount = 0;
2244 p_pic->i_status = DESTROYED_PICTURE;
2245 picture_CleanupQuant( p_pic );
2248 static void video_link_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2251 p_pic->i_refcount++;
2254 static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2257 video_release_buffer( p_pic );
2263 static subpicture_t *spu_new_buffer( decoder_t * );
2264 static void spu_del_buffer( decoder_t *, subpicture_t * );
2266 static int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2268 sout_stream_sys_t *p_sys = p_stream->p_sys;
2274 /* Initialization of decoder structures */
2275 id->p_decoder->pf_decode_sub = NULL;
2276 id->p_decoder->pf_spu_buffer_new = spu_new_buffer;
2277 id->p_decoder->pf_spu_buffer_del = spu_del_buffer;
2278 id->p_decoder->p_owner = (decoder_owner_sys_t *)p_stream;
2279 /* id->p_decoder->p_cfg = p_sys->p_spu_cfg; */
2281 id->p_decoder->p_module =
2282 module_need( id->p_decoder, "decoder", "$codec", false );
2284 if( !id->p_decoder->p_module )
2286 msg_Err( p_stream, "cannot find spu decoder" );
2287 return VLC_EGENERIC;
2290 if( !p_sys->b_soverlay )
2293 /* Initialization of encoder format structures */
2294 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2295 id->p_decoder->fmt_in.i_codec );
2297 id->p_encoder->p_cfg = p_sys->p_spu_cfg;
2299 id->p_encoder->p_module =
2300 module_need( id->p_encoder, "encoder", p_sys->psz_senc, true );
2302 if( !id->p_encoder->p_module )
2304 module_unneed( id->p_decoder, id->p_decoder->p_module );
2305 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_senc );
2306 return VLC_EGENERIC;
2312 p_sys->p_spu = spu_Create( p_stream );
2313 spu_Init( p_sys->p_spu );
2319 static void transcode_spu_close( sout_stream_id_t *id)
2322 if( id->p_decoder->p_module )
2323 module_unneed( id->p_decoder, id->p_decoder->p_module );
2324 if( id->p_decoder->p_description )
2325 vlc_meta_Delete( id->p_decoder->p_description );
2328 if( id->p_encoder->p_module )
2329 module_unneed( id->p_encoder, id->p_encoder->p_module );
2332 static int transcode_spu_process( sout_stream_t *p_stream,
2333 sout_stream_id_t *id,
2334 block_t *in, block_t **out )
2336 sout_stream_sys_t *p_sys = p_stream->p_sys;
2337 subpicture_t *p_subpic;
2340 p_subpic = id->p_decoder->pf_decode_sub( id->p_decoder, &in );
2342 return VLC_EGENERIC;
2344 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_SUBTITLE, 1 );
2346 if( p_sys->b_master_sync && p_sys->i_master_drift )
2348 p_subpic->i_start -= p_sys->i_master_drift;
2349 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2352 if( p_sys->b_soverlay )
2354 spu_DisplaySubpicture( p_sys->p_spu, p_subpic );
2360 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2361 spu_del_buffer( id->p_decoder, p_subpic );
2364 block_ChainAppend( out, p_block );
2369 return VLC_EGENERIC;
2372 static subpicture_t *spu_new_buffer( decoder_t *p_dec )
2374 VLC_UNUSED( p_dec );
2375 return subpicture_New();
2378 static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
2380 VLC_UNUSED( p_dec );
2381 subpicture_Delete( p_subpic );
2387 static int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2389 sout_stream_sys_t *p_sys = p_stream->p_sys;
2391 id->p_decoder->fmt_in.i_cat = SPU_ES;
2392 id->p_encoder->fmt_out.psz_language = strdup( "osd" );
2394 if( p_sys->i_osdcodec != 0 || p_sys->psz_osdenc )
2396 msg_Dbg( p_stream, "creating osdmenu transcoding from fcc=`%4.4s' "
2397 "to fcc=`%4.4s'", (char*)&id->p_encoder->fmt_out.i_codec,
2398 (char*)&p_sys->i_osdcodec );
2400 /* Complete destination format */
2401 id->p_encoder->fmt_out.i_codec = p_sys->i_osdcodec;
2404 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2405 VLC_FOURCC('Y','U','V','A') );
2406 id->p_encoder->fmt_in.psz_language = strdup( "osd" );
2408 id->p_encoder->p_cfg = p_sys->p_osd_cfg;
2410 id->p_encoder->p_module =
2411 module_need( id->p_encoder, "encoder", p_sys->psz_osdenc, true );
2413 if( !id->p_encoder->p_module )
2415 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_osdenc );
2419 /* open output stream */
2420 id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_encoder->fmt_out );
2421 id->b_transcode = true;
2423 if( !id->id ) goto error;
2427 msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
2428 (char*)&id->p_decoder->fmt_out.i_codec );
2429 id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_decoder->fmt_out );
2430 id->b_transcode = false;
2432 if( !id->id ) goto error;
2437 p_sys->p_spu = spu_Create( p_stream );
2438 spu_Init( p_sys->p_spu );
2444 msg_Err( p_stream, "starting osd encoding thread failed" );
2445 if( id->p_encoder->p_module )
2446 module_unneed( id->p_encoder, id->p_encoder->p_module );
2447 p_sys->b_osd = false;
2448 return VLC_EGENERIC;
2451 static void transcode_osd_close( sout_stream_t *p_stream, sout_stream_id_t *id)
2453 sout_stream_sys_t *p_sys = p_stream->p_sys;
2458 if( id->p_encoder->p_module )
2459 module_unneed( id->p_encoder, id->p_encoder->p_module );
2461 p_sys->b_osd = false;
2464 static int transcode_osd_process( sout_stream_t *p_stream,
2465 sout_stream_id_t *id,
2466 block_t *in, block_t **out )
2468 sout_stream_sys_t *p_sys = p_stream->p_sys;
2469 subpicture_t *p_subpic = NULL;
2471 /* Check if we have a subpicture to send */
2472 if( p_sys->p_spu && in->i_dts > 0)
2474 p_subpic = spu_SortSubpictures( p_sys->p_spu, in->i_dts, false, false );
2478 msg_Warn( p_stream, "spu channel not initialized, doing it now" );
2481 p_sys->p_spu = spu_Create( p_stream );
2482 spu_Init( p_sys->p_spu );
2488 block_t *p_block = NULL;
2490 if( p_sys->b_master_sync && p_sys->i_master_drift )
2492 p_subpic->i_start -= p_sys->i_master_drift;
2493 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2496 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2497 subpicture_Delete( p_subpic );
2500 p_block->i_dts = p_block->i_pts = in->i_dts;
2501 block_ChainAppend( out, p_block );
2505 return VLC_EGENERIC;