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 = malloc( sizeof( sout_stream_id_t ) );
699 memset( id, 0, sizeof(sout_stream_id_t) );
702 id->p_decoder = NULL;
703 id->p_encoder = NULL;
705 /* Create decoder object */
706 id->p_decoder = vlc_object_create( p_stream, VLC_OBJECT_DECODER );
709 vlc_object_attach( id->p_decoder, p_stream );
710 id->p_decoder->p_module = NULL;
711 id->p_decoder->fmt_in = *p_fmt;
712 id->p_decoder->b_pace_control = true;
714 /* Create encoder object */
715 id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
718 vlc_object_attach( id->p_encoder, p_stream );
719 id->p_encoder->p_module = NULL;
721 /* Create destination format */
722 es_format_Init( &id->p_encoder->fmt_out, p_fmt->i_cat, 0 );
723 id->p_encoder->fmt_out.i_id = p_fmt->i_id;
724 id->p_encoder->fmt_out.i_group = p_fmt->i_group;
725 if( p_fmt->psz_language )
726 id->p_encoder->fmt_out.psz_language = strdup( p_fmt->psz_language );
728 if( p_fmt->i_cat == AUDIO_ES && (p_sys->i_acodec || p_sys->psz_aenc) )
731 "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
732 (char*)&p_fmt->i_codec, (char*)&p_sys->i_acodec );
734 /* Complete destination format */
735 id->p_encoder->fmt_out.i_codec = p_sys->i_acodec;
736 id->p_encoder->fmt_out.audio.i_rate = p_sys->i_sample_rate > 0 ?
737 p_sys->i_sample_rate : p_fmt->audio.i_rate;
738 id->p_encoder->fmt_out.i_bitrate = p_sys->i_abitrate;
739 id->p_encoder->fmt_out.audio.i_bitspersample =
740 p_fmt->audio.i_bitspersample;
741 id->p_encoder->fmt_out.audio.i_channels = p_sys->i_channels > 0 ?
742 p_sys->i_channels : p_fmt->audio.i_channels;
743 /* Sanity check for audio channels */
744 id->p_encoder->fmt_out.audio.i_channels =
745 __MIN( id->p_encoder->fmt_out.audio.i_channels,
746 id->p_decoder->fmt_in.audio.i_channels );
747 id->p_encoder->fmt_out.audio.i_original_channels =
748 id->p_decoder->fmt_in.audio.i_physical_channels;
749 if( id->p_decoder->fmt_in.audio.i_channels ==
750 id->p_encoder->fmt_out.audio.i_channels )
752 id->p_encoder->fmt_out.audio.i_physical_channels =
753 id->p_decoder->fmt_in.audio.i_physical_channels;
757 id->p_encoder->fmt_out.audio.i_physical_channels =
758 pi_channels_maps[id->p_encoder->fmt_out.audio.i_channels];
761 /* Build decoder -> filter -> encoder chain */
762 if( transcode_audio_new( p_stream, id ) )
764 msg_Err( p_stream, "cannot create audio chain" );
768 /* Open output stream */
769 id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_encoder->fmt_out );
770 id->b_transcode = true;
774 transcode_audio_close( id );
778 date_Init( &id->interpolated_pts, p_fmt->audio.i_rate, 1 );
780 else if( p_fmt->i_cat == VIDEO_ES &&
781 (p_sys->i_vcodec != 0 || p_sys->psz_venc) )
784 "creating video transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
785 (char*)&p_fmt->i_codec, (char*)&p_sys->i_vcodec );
787 /* Complete destination format */
788 id->p_encoder->fmt_out.i_codec = p_sys->i_vcodec;
789 id->p_encoder->fmt_out.video.i_width = p_sys->i_width & ~1;
790 id->p_encoder->fmt_out.video.i_height = p_sys->i_height & ~1;
791 id->p_encoder->fmt_out.i_bitrate = p_sys->i_vbitrate;
793 /* Build decoder -> filter -> encoder chain */
794 if( transcode_video_new( p_stream, id ) )
796 msg_Err( p_stream, "cannot create video chain" );
800 /* Stream will be added later on because we don't know
801 * all the characteristics of the decoded stream yet */
802 id->b_transcode = true;
804 if( p_sys->f_fps > 0 )
806 id->p_encoder->fmt_out.video.i_frame_rate =
807 (p_sys->f_fps * 1000) + 0.5;
808 id->p_encoder->fmt_out.video.i_frame_rate_base =
812 else if( ( p_fmt->i_cat == SPU_ES ) &&
813 ( p_sys->i_scodec || p_sys->psz_senc ) )
815 msg_Dbg( p_stream, "creating subtitles transcoding from fcc=`%4.4s' "
816 "to fcc=`%4.4s'", (char*)&p_fmt->i_codec,
817 (char*)&p_sys->i_scodec );
819 /* Complete destination format */
820 id->p_encoder->fmt_out.i_codec = p_sys->i_scodec;
822 /* build decoder -> filter -> encoder */
823 if( transcode_spu_new( p_stream, id ) )
825 msg_Err( p_stream, "cannot create subtitles chain" );
829 /* open output stream */
830 id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_encoder->fmt_out );
831 id->b_transcode = true;
835 transcode_spu_close( id );
839 else if( p_fmt->i_cat == SPU_ES && p_sys->b_soverlay )
841 msg_Dbg( p_stream, "subtitles (fcc=`%4.4s') overlaying",
842 (char*)&p_fmt->i_codec );
844 id->b_transcode = true;
846 /* Build decoder -> filter -> overlaying chain */
847 if( transcode_spu_new( p_stream, id ) )
849 msg_Err( p_stream, "cannot create subtitles chain" );
853 else if( !p_sys->b_osd && (p_sys->i_osdcodec != 0 || p_sys->psz_osdenc) )
855 msg_Dbg( p_stream, "creating osd transcoding from fcc=`%4.4s' "
856 "to fcc=`%4.4s'", (char*)&p_fmt->i_codec,
857 (char*)&p_sys->i_scodec );
859 id->b_transcode = true;
861 /* Create a fake OSD menu elementary stream */
862 if( transcode_osd_new( p_stream, id ) )
864 msg_Err( p_stream, "cannot create osd chain" );
871 msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
872 (char*)&p_fmt->i_codec );
873 id->id = sout_StreamIdAdd( p_sys->p_out, p_fmt );
874 id->b_transcode = false;
876 if( !id->id ) goto error;
886 vlc_object_detach( id->p_decoder );
887 vlc_object_release( id->p_decoder );
888 id->p_decoder = NULL;
893 vlc_object_detach( id->p_encoder );
894 es_format_Clean( &id->p_encoder->fmt_out );
895 vlc_object_release( id->p_encoder );
896 id->p_encoder = NULL;
904 static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
906 sout_stream_sys_t *p_sys = p_stream->p_sys;
908 if( id->b_transcode )
910 switch( id->p_decoder->fmt_in.i_cat )
913 transcode_audio_close( id );
916 transcode_video_close( p_stream, id );
920 transcode_osd_close( p_stream, id );
922 transcode_spu_close( id );
927 if( id->id ) sout_StreamIdDel( p_sys->p_out, id->id );
931 vlc_object_detach( id->p_decoder );
932 vlc_object_release( id->p_decoder );
933 id->p_decoder = NULL;
938 vlc_object_detach( id->p_encoder );
939 es_format_Clean( &id->p_encoder->fmt_out );
940 vlc_object_release( id->p_encoder );
941 id->p_encoder = NULL;
948 static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
951 sout_stream_sys_t *p_sys = p_stream->p_sys;
952 block_t *p_out = NULL;
954 if( !id->b_transcode )
957 return sout_StreamIdSend( p_sys->p_out, id->id, p_buffer );
959 block_Release( p_buffer );
963 switch( id->p_decoder->fmt_in.i_cat )
966 transcode_audio_process( p_stream, id, p_buffer, &p_out );
970 if( transcode_video_process( p_stream, id, p_buffer, &p_out )
978 /* Transcode OSD menu pictures. */
981 if( transcode_osd_process( p_stream, id, p_buffer, &p_out ) !=
987 else if ( transcode_spu_process( p_stream, id, p_buffer, &p_out ) !=
996 block_Release( p_buffer );
1001 return sout_StreamIdSend( p_sys->p_out, id->id, p_out );
1005 /****************************************************************************
1007 ****************************************************************************/
1008 static inline void video_timer_start( encoder_t * p_encoder )
1010 stats_TimerStart( p_encoder, "encoding video frame",
1011 STATS_TIMER_VIDEO_FRAME_ENCODING );
1014 static inline void video_timer_stop( encoder_t * p_encoder )
1016 stats_TimerStop( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1019 static inline void video_timer_close( encoder_t * p_encoder )
1021 stats_TimerDump( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1022 stats_TimerClean( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1025 static inline void audio_timer_start( encoder_t * p_encoder )
1027 stats_TimerStart( p_encoder, "encoding audio frame",
1028 STATS_TIMER_AUDIO_FRAME_ENCODING );
1031 static inline void audio_timer_stop( encoder_t * p_encoder )
1033 stats_TimerStop( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1036 static inline void audio_timer_close( encoder_t * p_encoder )
1038 stats_TimerDump( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1039 stats_TimerClean( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1042 /****************************************************************************
1043 * decoder reencoder part
1044 ****************************************************************************/
1046 static block_t *transcode_audio_alloc( filter_t *p_filter, int size )
1048 VLC_UNUSED( p_filter );
1049 return block_Alloc( size );
1052 static int transcode_audio_filter_allocation_init( filter_t *p_filter,
1056 p_filter->pf_audio_buffer_new = transcode_audio_alloc;
1060 static int transcode_audio_new( sout_stream_t *p_stream,
1061 sout_stream_id_t *id )
1063 sout_stream_sys_t *p_sys = p_stream->p_sys;
1064 es_format_t fmt_last;
1071 /* Initialization of decoder structures */
1072 id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1073 id->p_decoder->fmt_out.i_extra = 0;
1074 id->p_decoder->fmt_out.p_extra = 0;
1075 id->p_decoder->pf_decode_audio = NULL;
1076 id->p_decoder->pf_aout_buffer_new = audio_new_buffer;
1077 id->p_decoder->pf_aout_buffer_del = audio_del_buffer;
1078 /* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */
1080 id->p_decoder->p_module =
1081 module_need( id->p_decoder, "decoder", "$codec", 0 );
1082 if( !id->p_decoder->p_module )
1084 msg_Err( p_stream, "cannot find audio decoder" );
1085 return VLC_EGENERIC;
1087 id->p_decoder->fmt_out.audio.i_bitspersample =
1088 aout_BitsPerSample( id->p_decoder->fmt_out.i_codec );
1089 fmt_last = id->p_decoder->fmt_out;
1090 /* Fix AAC SBR changing number of channels and sampling rate */
1091 if( !(id->p_decoder->fmt_in.i_codec == VLC_FOURCC('m','p','4','a') &&
1092 fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate &&
1093 fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels) )
1094 fmt_last.audio.i_rate = id->p_decoder->fmt_in.audio.i_rate;
1100 /* Initialization of encoder format structures */
1101 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1102 id->p_decoder->fmt_out.i_codec );
1103 id->p_encoder->fmt_in.audio.i_format = id->p_decoder->fmt_out.i_codec;
1105 id->p_encoder->fmt_in.audio.i_rate = id->p_encoder->fmt_out.audio.i_rate;
1106 id->p_encoder->fmt_in.audio.i_physical_channels =
1107 id->p_encoder->fmt_out.audio.i_physical_channels;
1108 id->p_encoder->fmt_in.audio.i_original_channels =
1109 id->p_encoder->fmt_out.audio.i_original_channels;
1110 id->p_encoder->fmt_in.audio.i_channels =
1111 id->p_encoder->fmt_out.audio.i_channels;
1112 id->p_encoder->fmt_in.audio.i_bitspersample =
1113 aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1115 id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1116 id->p_encoder->p_module =
1117 module_need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1118 if( !id->p_encoder->p_module )
1120 msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)",
1121 p_sys->psz_aenc ? p_sys->psz_aenc : "any",
1122 (char *)&p_sys->i_acodec );
1123 module_unneed( id->p_decoder, id->p_decoder->p_module );
1124 id->p_decoder->p_module = NULL;
1125 return VLC_EGENERIC;
1127 id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1128 id->p_encoder->fmt_in.audio.i_bitspersample =
1129 aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1131 /* Init filter chain */
1132 id->p_f_chain = filter_chain_New( p_stream, "audio filter2", true,
1133 transcode_audio_filter_allocation_init, NULL, NULL );
1134 filter_chain_Reset( id->p_f_chain, &fmt_last, &id->p_encoder->fmt_in );
1136 /* Load conversion filters */
1137 if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels ||
1138 fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1140 /* We'll have to go through fl32 first */
1141 fmt_last.i_codec = fmt_last.audio.i_format = VLC_FOURCC('f','l','3','2');
1142 fmt_last.audio.i_bitspersample = aout_BitsPerSample( fmt_last.i_codec );
1143 filter_chain_AppendFilter( id->p_f_chain, NULL, NULL, NULL, &fmt_last );
1144 fmt_last = *filter_chain_GetFmtOut( id->p_f_chain );
1147 for( i = 0; i < 4; i++ )
1149 if( (fmt_last.audio.i_channels !=
1150 id->p_encoder->fmt_in.audio.i_channels) ||
1151 (fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate) ||
1152 (fmt_last.i_codec != id->p_encoder->fmt_in.i_codec) )
1154 msg_Dbg( p_stream, "Looking for filter "
1155 "(%4.4s->%4.4s, channels %d->%d, rate %d->%d)",
1156 (char *)&fmt_last.i_codec,
1157 (char *)&id->p_encoder->fmt_in.i_codec,
1158 fmt_last.audio.i_channels,
1159 id->p_encoder->fmt_in.audio.i_channels,
1160 fmt_last.audio.i_rate,
1161 id->p_encoder->fmt_in.audio.i_rate );
1162 filter_chain_AppendFilter( id->p_f_chain, NULL, NULL,
1163 &fmt_last, &id->p_encoder->fmt_in );
1164 fmt_last = *filter_chain_GetFmtOut( id->p_f_chain );
1169 /* Final checks to see if conversions were successful */
1170 if( fmt_last.i_codec != id->p_encoder->fmt_in.i_codec )
1172 msg_Err( p_stream, "no audio filter found "
1173 "(%4.4s->%4.4s, channels %d->%d, rate %d->%d)",
1174 (char *)&fmt_last.i_codec,
1175 (char *)&id->p_encoder->fmt_in.i_codec,
1176 fmt_last.audio.i_channels,
1177 id->p_encoder->fmt_in.audio.i_channels,
1178 fmt_last.audio.i_rate,
1179 id->p_encoder->fmt_in.audio.i_rate );
1180 transcode_audio_close( id );
1181 return VLC_EGENERIC;
1184 /* Load user specified audio filters now */
1185 if( p_sys->psz_af2 )
1187 id->p_uf_chain = filter_chain_New( p_stream, "audio filter2", false,
1188 transcode_audio_filter_allocation_init, NULL, NULL );
1189 filter_chain_Reset( id->p_uf_chain, &fmt_last, &id->p_encoder->fmt_in );
1190 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_af2 );
1191 fmt_last = *filter_chain_GetFmtOut( id->p_uf_chain );
1194 if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels )
1197 module_unneed( id->p_encoder, id->p_encoder->p_module );
1198 id->p_encoder->p_module = NULL;
1200 /* This might work, but only if the encoder is restarted */
1201 id->p_encoder->fmt_in.audio.i_channels = fmt_last.audio.i_channels;
1202 id->p_encoder->fmt_out.audio.i_channels = fmt_last.audio.i_channels;
1204 id->p_encoder->fmt_in.audio.i_physical_channels =
1205 id->p_encoder->fmt_in.audio.i_original_channels =
1206 fmt_last.audio.i_physical_channels;
1207 id->p_encoder->fmt_out.audio.i_physical_channels =
1208 id->p_encoder->fmt_out.audio.i_original_channels =
1209 fmt_last.audio.i_physical_channels;
1211 msg_Dbg( p_stream, "number of audio channels for mixing changed, "
1212 "trying to reopen the encoder for mixing %i to %i channels",
1213 fmt_last.audio.i_channels,
1214 id->p_encoder->fmt_in.audio.i_channels );
1216 /* reload encoder */
1217 id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1218 id->p_encoder->p_module =
1219 module_need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1220 if( !id->p_encoder->p_module ||
1221 fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels ||
1222 fmt_last.i_codec != id->p_encoder->fmt_in.i_codec )
1224 if( id->p_encoder->p_module )
1226 module_unneed( id->p_encoder, id->p_encoder->p_module );
1227 id->p_encoder->p_module = NULL;
1229 msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)",
1230 p_sys->psz_aenc ? p_sys->psz_aenc : "any",
1231 (char *)&p_sys->i_acodec );
1232 transcode_audio_close( id );
1233 return VLC_EGENERIC;
1235 id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1236 id->p_encoder->fmt_in.audio.i_bitspersample =
1237 aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1239 msg_Err( p_stream, "no audio filter found for mixing from"
1240 " %i to %i channels", fmt_last.audio.i_channels,
1241 id->p_encoder->fmt_in.audio.i_channels );
1243 transcode_audio_close( id );
1244 return VLC_EGENERIC;
1248 if( fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1250 msg_Err( p_stream, "no audio filter found for resampling from"
1251 " %iHz to %iHz", fmt_last.audio.i_rate,
1252 id->p_encoder->fmt_in.audio.i_rate );
1254 /* FIXME : this might work, but only if the encoder is restarted */
1255 id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;
1256 id->p_encoder->fmt_out.audio.i_rate = fmt_last.audio.i_rate;
1258 transcode_audio_close( id );
1259 return VLC_EGENERIC;
1263 /* FIXME: Hack for mp3 transcoding support */
1264 if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC( 'm','p','3',' ' ) )
1265 id->p_encoder->fmt_out.i_codec = VLC_FOURCC( 'm','p','g','a' );
1270 static void transcode_audio_close( sout_stream_id_t *id )
1272 audio_timer_close( id->p_encoder );
1275 if( id->p_decoder->p_module )
1276 module_unneed( id->p_decoder, id->p_decoder->p_module );
1277 id->p_decoder->p_module = NULL;
1279 if( id->p_decoder->p_description )
1280 vlc_meta_Delete( id->p_decoder->p_description );
1281 id->p_decoder->p_description = NULL;
1284 if( id->p_encoder->p_module )
1285 module_unneed( id->p_encoder, id->p_encoder->p_module );
1286 id->p_encoder->p_module = NULL;
1290 filter_chain_Delete( id->p_f_chain );
1291 if( id->p_uf_chain )
1292 filter_chain_Delete( id->p_uf_chain );
1295 static int transcode_audio_process( sout_stream_t *p_stream,
1296 sout_stream_id_t *id,
1297 block_t *in, block_t **out )
1299 sout_stream_sys_t *p_sys = p_stream->p_sys;
1300 aout_buffer_t *p_audio_buf;
1301 block_t *p_block, *p_audio_block;
1304 while( (p_audio_buf = id->p_decoder->pf_decode_audio( id->p_decoder,
1307 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_AUDIO, 1 );
1308 if( p_sys->b_master_sync )
1310 mtime_t i_dts = date_Get( &id->interpolated_pts ) + 1;
1311 if ( p_audio_buf->start_date - i_dts > MASTER_SYNC_MAX_DRIFT
1312 || p_audio_buf->start_date - i_dts < -MASTER_SYNC_MAX_DRIFT )
1314 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1315 date_Set( &id->interpolated_pts, p_audio_buf->start_date );
1316 i_dts = p_audio_buf->start_date + 1;
1318 p_sys->i_master_drift = p_audio_buf->start_date - i_dts;
1319 date_Increment( &id->interpolated_pts, p_audio_buf->i_nb_samples );
1320 p_audio_buf->start_date -= p_sys->i_master_drift;
1321 p_audio_buf->end_date -= p_sys->i_master_drift;
1324 p_audio_block = p_audio_buf->p_sys;
1325 p_audio_block->i_buffer = p_audio_buf->i_nb_bytes;
1326 p_audio_block->i_dts = p_audio_block->i_pts =
1327 p_audio_buf->start_date;
1328 p_audio_block->i_length = p_audio_buf->end_date -
1329 p_audio_buf->start_date;
1330 p_audio_block->i_samples = p_audio_buf->i_nb_samples;
1332 /* Run filter chain */
1333 p_audio_block = filter_chain_AudioFilter( id->p_f_chain, p_audio_block );
1334 if( id->p_uf_chain )
1335 p_audio_block = filter_chain_AudioFilter( id->p_uf_chain, p_audio_block );
1336 assert( p_audio_block );
1338 p_audio_buf->p_buffer = p_audio_block->p_buffer;
1339 p_audio_buf->i_nb_bytes = p_audio_block->i_buffer;
1340 p_audio_buf->i_nb_samples = p_audio_block->i_samples;
1341 p_audio_buf->start_date = p_audio_block->i_dts;
1342 p_audio_buf->end_date = p_audio_block->i_dts + p_audio_block->i_length;
1344 audio_timer_start( id->p_encoder );
1345 p_block = id->p_encoder->pf_encode_audio( id->p_encoder, p_audio_buf );
1346 audio_timer_stop( id->p_encoder );
1348 block_ChainAppend( out, p_block );
1349 block_Release( p_audio_block );
1350 free( p_audio_buf );
1356 static void audio_release_buffer( aout_buffer_t *p_buffer )
1358 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1362 static aout_buffer_t *audio_new_buffer( decoder_t *p_dec, int i_samples )
1364 aout_buffer_t *p_buffer;
1368 if( p_dec->fmt_out.audio.i_bitspersample )
1370 i_size = i_samples * p_dec->fmt_out.audio.i_bitspersample / 8 *
1371 p_dec->fmt_out.audio.i_channels;
1373 else if( p_dec->fmt_out.audio.i_bytes_per_frame &&
1374 p_dec->fmt_out.audio.i_frame_length )
1376 i_size = i_samples * p_dec->fmt_out.audio.i_bytes_per_frame /
1377 p_dec->fmt_out.audio.i_frame_length;
1381 i_size = i_samples * 4 * p_dec->fmt_out.audio.i_channels;
1384 p_buffer = malloc( sizeof(aout_buffer_t) );
1385 if( !p_buffer ) return NULL;
1386 p_buffer->b_discontinuity = false;
1387 p_buffer->pf_release = audio_release_buffer;
1388 p_buffer->p_sys = p_block = block_New( p_dec, i_size );
1390 p_buffer->p_buffer = p_block->p_buffer;
1391 p_buffer->i_size = p_buffer->i_nb_bytes = p_block->i_buffer;
1392 p_buffer->i_nb_samples = i_samples;
1393 p_block->i_samples = i_samples;
1398 static void audio_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
1401 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1409 static int transcode_video_filter_allocation_init( filter_t *p_filter,
1412 sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_data;
1415 p_filter->pf_vout_buffer_new = video_new_buffer_filter;
1416 p_filter->pf_vout_buffer_del = video_del_buffer_filter;
1418 p_filter->p_owner = malloc( sizeof(filter_owner_sys_t) );
1419 if( !p_filter->p_owner )
1420 return VLC_EGENERIC;
1422 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1423 p_filter->p_owner->pp_pics[i] = 0;
1424 p_filter->p_owner->p_sys = p_sys;
1429 static void transcode_video_filter_allocation_clear( filter_t *p_filter )
1433 /* Clean-up pictures ring buffer */
1434 for( j = 0; j < PICTURE_RING_SIZE; j++ )
1436 if( p_filter->p_owner->pp_pics[j] )
1437 video_del_buffer( VLC_OBJECT(p_filter),
1438 p_filter->p_owner->pp_pics[j] );
1440 free( p_filter->p_owner );
1443 static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
1445 sout_stream_sys_t *p_sys = p_stream->p_sys;
1449 * Initialization of decoder structures
1451 id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1452 id->p_decoder->fmt_out.i_extra = 0;
1453 id->p_decoder->fmt_out.p_extra = 0;
1454 id->p_decoder->pf_decode_video = NULL;
1455 id->p_decoder->pf_get_cc = NULL;
1456 id->p_decoder->pf_get_cc = 0;
1457 id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
1458 id->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder;
1459 id->p_decoder->pf_picture_link = video_link_picture_decoder;
1460 id->p_decoder->pf_picture_unlink = video_unlink_picture_decoder;
1461 id->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) );
1462 if( !id->p_decoder->p_owner )
1463 return VLC_EGENERIC;
1465 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1466 id->p_decoder->p_owner->pp_pics[i] = 0;
1467 id->p_decoder->p_owner->p_sys = p_sys;
1468 /* id->p_decoder->p_cfg = p_sys->p_video_cfg; */
1470 id->p_decoder->p_module =
1471 module_need( id->p_decoder, "decoder", "$codec", 0 );
1473 if( !id->p_decoder->p_module )
1475 msg_Err( p_stream, "cannot find video decoder" );
1476 free( id->p_decoder->p_owner );
1477 return VLC_EGENERIC;
1482 * Because some info about the decoded input will only be available
1483 * once the first frame is decoded, we actually only test the availability
1484 * of the encoder here.
1487 /* Initialization of encoder format structures */
1488 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1489 id->p_decoder->fmt_out.i_codec );
1490 id->p_encoder->fmt_in.video.i_chroma = id->p_decoder->fmt_out.i_codec;
1492 /* The dimensions will be set properly later on.
1493 * Just put sensible values so we can test an encoder is available. */
1494 id->p_encoder->fmt_in.video.i_width =
1495 id->p_encoder->fmt_out.video.i_width ?:
1496 id->p_decoder->fmt_in.video.i_width ?: 16;
1497 id->p_encoder->fmt_in.video.i_height =
1498 id->p_encoder->fmt_out.video.i_height ?:
1499 id->p_decoder->fmt_in.video.i_height ?: 16;
1500 id->p_encoder->fmt_in.video.i_frame_rate = ENC_FRAMERATE;
1501 id->p_encoder->fmt_in.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1503 id->p_encoder->i_threads = p_sys->i_threads;
1504 id->p_encoder->p_cfg = p_sys->p_video_cfg;
1506 id->p_encoder->p_module =
1507 module_need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1508 if( !id->p_encoder->p_module )
1510 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1511 p_sys->psz_venc ? p_sys->psz_venc : "any",
1512 (char *)&p_sys->i_vcodec );
1513 module_unneed( id->p_decoder, id->p_decoder->p_module );
1514 id->p_decoder->p_module = 0;
1515 free( id->p_decoder->p_owner );
1516 return VLC_EGENERIC;
1519 /* Close the encoder.
1520 * We'll open it only when we have the first frame. */
1521 module_unneed( id->p_encoder, id->p_encoder->p_module );
1522 if( id->p_encoder->fmt_out.p_extra )
1524 free( id->p_encoder->fmt_out.p_extra );
1525 id->p_encoder->fmt_out.p_extra = NULL;
1526 id->p_encoder->fmt_out.i_extra = 0;
1528 id->p_encoder->p_module = NULL;
1530 if( p_sys->i_threads >= 1 )
1532 int i_priority = p_sys->b_high_priority ? VLC_THREAD_PRIORITY_OUTPUT :
1533 VLC_THREAD_PRIORITY_VIDEO;
1534 p_sys->id_video = id;
1535 vlc_mutex_init( &p_sys->lock_out );
1536 vlc_cond_init( &p_sys->cond );
1537 memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) );
1538 p_sys->i_first_pic = 0;
1539 p_sys->i_last_pic = 0;
1540 p_sys->p_buffers = NULL;
1541 p_sys->b_die = p_sys->b_error = 0;
1542 if( vlc_thread_create( p_sys, "encoder", EncoderThread, i_priority,
1545 msg_Err( p_stream, "cannot spawn encoder thread" );
1546 module_unneed( id->p_decoder, id->p_decoder->p_module );
1547 id->p_decoder->p_module = 0;
1548 free( id->p_decoder->p_owner );
1549 return VLC_EGENERIC;
1556 static void transcode_video_encoder_init( sout_stream_t *p_stream,
1557 sout_stream_id_t *id )
1559 sout_stream_sys_t *p_sys = p_stream->p_sys;
1561 /* Calculate scaling
1562 * width/height of source */
1563 int i_src_width = id->p_decoder->fmt_out.video.i_width;
1564 int i_src_height = id->p_decoder->fmt_out.video.i_height;
1566 /* with/height scaling */
1567 float f_scale_width = 1;
1568 float f_scale_height = 1;
1570 /* width/height of output stream */
1575 float f_aspect = (float)id->p_decoder->fmt_out.video.i_aspect /
1578 msg_Dbg( p_stream, "decoder aspect is %i:%i",
1579 id->p_decoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1581 /* Change f_aspect from source frame to source pixel */
1582 f_aspect = f_aspect * i_src_height / i_src_width;
1583 msg_Dbg( p_stream, "source pixel aspect is %f:1", f_aspect );
1585 /* Calculate scaling factor for specified parameters */
1586 if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1587 id->p_encoder->fmt_out.video.i_height <= 0 && p_sys->f_scale )
1589 /* Global scaling. Make sure width will remain a factor of 16 */
1592 int i_new_width = i_src_width * p_sys->f_scale;
1594 if( i_new_width % 16 <= 7 && i_new_width >= 16 )
1595 i_new_width -= i_new_width % 16;
1597 i_new_width += 16 - i_new_width % 16;
1599 f_real_scale = (float)( i_new_width ) / (float) i_src_width;
1601 i_new_height = __MAX( 16, i_src_height * (float)f_real_scale );
1603 f_scale_width = f_real_scale;
1604 f_scale_height = (float) i_new_height / (float) i_src_height;
1606 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1607 id->p_encoder->fmt_out.video.i_height <= 0 )
1609 /* Only width specified */
1610 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1611 f_scale_height = f_scale_width;
1613 else if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1614 id->p_encoder->fmt_out.video.i_height > 0 )
1616 /* Only height specified */
1617 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1618 f_scale_width = f_scale_height;
1620 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1621 id->p_encoder->fmt_out.video.i_height > 0 )
1623 /* Width and height specified */
1624 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1625 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1628 /* check maxwidth and maxheight
1630 if( p_sys->i_maxwidth && f_scale_width > (float)p_sys->i_maxwidth /
1633 f_scale_width = (float)p_sys->i_maxwidth / i_src_width;
1636 if( p_sys->i_maxheight && f_scale_height > (float)p_sys->i_maxheight /
1639 f_scale_height = (float)p_sys->i_maxheight / i_src_height;
1643 /* Change aspect ratio from source pixel to scaled pixel */
1644 f_aspect = f_aspect * f_scale_height / f_scale_width;
1645 msg_Dbg( p_stream, "scaled pixel aspect is %f:1", f_aspect );
1647 /* f_scale_width and f_scale_height are now final */
1648 /* Calculate width, height from scaling
1649 * Make sure its multiple of 2
1651 i_dst_width = 2 * (int)(f_scale_width*i_src_width/2+0.5);
1652 i_dst_height = 2 * (int)(f_scale_height*i_src_height/2+0.5);
1654 /* Change aspect ratio from scaled pixel to output frame */
1655 f_aspect = f_aspect * i_dst_width / i_dst_height;
1657 /* Store calculated values */
1658 id->p_encoder->fmt_out.video.i_width =
1659 id->p_encoder->fmt_out.video.i_visible_width = i_dst_width;
1660 id->p_encoder->fmt_out.video.i_height =
1661 id->p_encoder->fmt_out.video.i_visible_height = i_dst_height;
1663 id->p_encoder->fmt_in.video.i_width =
1664 id->p_encoder->fmt_in.video.i_visible_width = i_dst_width;
1665 id->p_encoder->fmt_in.video.i_height =
1666 id->p_encoder->fmt_in.video.i_visible_height = i_dst_height;
1668 msg_Dbg( p_stream, "source %ix%i, destination %ix%i",
1669 i_src_width, i_src_height,
1670 i_dst_width, i_dst_height
1673 /* Handle frame rate conversion */
1674 if( !id->p_encoder->fmt_out.video.i_frame_rate ||
1675 !id->p_encoder->fmt_out.video.i_frame_rate_base )
1677 if( id->p_decoder->fmt_out.video.i_frame_rate &&
1678 id->p_decoder->fmt_out.video.i_frame_rate_base )
1680 id->p_encoder->fmt_out.video.i_frame_rate =
1681 id->p_decoder->fmt_out.video.i_frame_rate;
1682 id->p_encoder->fmt_out.video.i_frame_rate_base =
1683 id->p_decoder->fmt_out.video.i_frame_rate_base;
1687 /* Pick a sensible default value */
1688 id->p_encoder->fmt_out.video.i_frame_rate = ENC_FRAMERATE;
1689 id->p_encoder->fmt_out.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1693 id->p_encoder->fmt_in.video.i_frame_rate =
1694 id->p_encoder->fmt_out.video.i_frame_rate;
1695 id->p_encoder->fmt_in.video.i_frame_rate_base =
1696 id->p_encoder->fmt_out.video.i_frame_rate_base;
1698 date_Init( &id->interpolated_pts,
1699 id->p_encoder->fmt_out.video.i_frame_rate,
1700 id->p_encoder->fmt_out.video.i_frame_rate_base );
1702 /* Check whether a particular aspect ratio was requested */
1703 if( !id->p_encoder->fmt_out.video.i_aspect )
1705 id->p_encoder->fmt_out.video.i_aspect =
1706 (int)( f_aspect * VOUT_ASPECT_FACTOR + 0.5 );
1708 id->p_encoder->fmt_in.video.i_aspect =
1709 id->p_encoder->fmt_out.video.i_aspect;
1711 msg_Dbg( p_stream, "encoder aspect is %i:%i",
1712 id->p_encoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1714 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1717 static int transcode_video_encoder_open( sout_stream_t *p_stream,
1718 sout_stream_id_t *id )
1720 sout_stream_sys_t *p_sys = p_stream->p_sys;
1723 msg_Dbg( p_stream, "destination (after video filters) %ix%i",
1724 id->p_encoder->fmt_in.video.i_width,
1725 id->p_encoder->fmt_in.video.i_height );
1727 id->p_encoder->p_module =
1728 module_need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1729 if( !id->p_encoder->p_module )
1731 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1732 p_sys->psz_venc ? p_sys->psz_venc : "any",
1733 (char *)&p_sys->i_vcodec );
1734 return VLC_EGENERIC;
1737 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1739 /* Hack for mp2v/mp1v transcoding support */
1740 if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','1','v') ||
1741 id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','2','v') )
1743 id->p_encoder->fmt_out.i_codec = VLC_FOURCC('m','p','g','v');
1746 id->id = sout_StreamIdAdd( p_stream->p_sys->p_out,
1747 &id->p_encoder->fmt_out );
1750 msg_Err( p_stream, "cannot add this stream" );
1751 return VLC_EGENERIC;
1757 static void transcode_video_close( sout_stream_t *p_stream,
1758 sout_stream_id_t *id )
1762 if( p_stream->p_sys->i_threads >= 1 )
1764 vlc_mutex_lock( &p_stream->p_sys->lock_out );
1765 vlc_object_kill( p_stream->p_sys );
1766 vlc_cond_signal( &p_stream->p_sys->cond );
1767 vlc_mutex_unlock( &p_stream->p_sys->lock_out );
1768 vlc_thread_join( p_stream->p_sys );
1769 vlc_mutex_destroy( &p_stream->p_sys->lock_out );
1770 vlc_cond_destroy( &p_stream->p_sys->cond );
1773 video_timer_close( id->p_encoder );
1776 if( id->p_decoder->p_module )
1777 module_unneed( id->p_decoder, id->p_decoder->p_module );
1778 if( id->p_decoder->p_description )
1779 vlc_meta_Delete( id->p_decoder->p_description );
1781 if( id->p_decoder->p_owner )
1783 /* Clean-up pictures ring buffer */
1784 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1786 if( id->p_decoder->p_owner->pp_pics[i] )
1787 video_del_buffer( VLC_OBJECT(id->p_decoder),
1788 id->p_decoder->p_owner->pp_pics[i] );
1790 free( id->p_decoder->p_owner );
1794 if( id->p_encoder->p_module )
1795 module_unneed( id->p_encoder, id->p_encoder->p_module );
1799 filter_chain_Delete( id->p_f_chain );
1800 if( id->p_uf_chain )
1801 filter_chain_Delete( id->p_uf_chain );
1804 static int transcode_video_process( sout_stream_t *p_stream,
1805 sout_stream_id_t *id,
1806 block_t *in, block_t **out )
1808 sout_stream_sys_t *p_sys = p_stream->p_sys;
1809 int i_duplicate = 1;
1810 picture_t *p_pic, *p_pic2 = NULL;
1813 while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
1815 subpicture_t *p_subpic = NULL;
1817 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_VIDEO, 1 );
1819 if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )
1821 mtime_t current_date = mdate();
1822 if( current_date + 50000 > p_pic->date )
1824 msg_Dbg( p_stream, "late picture skipped (%"PRId64")",
1825 current_date + 50000 - p_pic->date );
1826 p_pic->pf_release( p_pic );
1831 if( p_sys->b_master_sync )
1833 mtime_t i_video_drift;
1834 mtime_t i_master_drift = p_sys->i_master_drift;
1837 i_pts = date_Get( &id->interpolated_pts ) + 1;
1838 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1839 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
1841 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1842 date_Set( &id->interpolated_pts, p_pic->date );
1843 i_pts = p_pic->date + 1;
1845 i_video_drift = p_pic->date - i_pts;
1848 /* Set the pts of the frame being encoded */
1849 p_pic->date = i_pts;
1851 if( i_video_drift < (i_master_drift - 50000) )
1854 msg_Dbg( p_stream, "dropping frame (%i)",
1855 (int)(i_video_drift - i_master_drift) );
1857 p_pic->pf_release( p_pic );
1860 else if( i_video_drift > (i_master_drift + 50000) )
1863 msg_Dbg( p_stream, "adding frame (%i)",
1864 (int)(i_video_drift - i_master_drift) );
1870 if( !id->p_encoder->p_module )
1872 transcode_video_encoder_init( p_stream, id );
1874 id->p_f_chain = filter_chain_New( p_stream, "video filter2",
1876 transcode_video_filter_allocation_init,
1877 transcode_video_filter_allocation_clear,
1881 if( p_stream->p_sys->b_deinterlace )
1883 filter_chain_AppendFilter( id->p_f_chain,
1884 p_sys->psz_deinterlace,
1885 p_sys->p_deinterlace_cfg,
1886 &id->p_decoder->fmt_out,
1887 &id->p_decoder->fmt_out );
1890 /* Take care of the scaling and chroma conversions */
1891 if( ( id->p_decoder->fmt_out.video.i_chroma !=
1892 id->p_encoder->fmt_in.video.i_chroma ) ||
1893 ( id->p_decoder->fmt_out.video.i_width !=
1894 id->p_encoder->fmt_in.video.i_width ) ||
1895 ( id->p_decoder->fmt_out.video.i_height !=
1896 id->p_encoder->fmt_in.video.i_height ) )
1898 filter_chain_AppendFilter( id->p_f_chain,
1900 &id->p_decoder->fmt_out,
1901 &id->p_encoder->fmt_in );
1904 if( p_sys->psz_vf2 )
1906 const es_format_t *p_fmt_out;
1907 id->p_uf_chain = filter_chain_New( p_stream, "video filter2",
1909 transcode_video_filter_allocation_init,
1910 transcode_video_filter_allocation_clear,
1912 filter_chain_Reset( id->p_uf_chain, &id->p_encoder->fmt_in,
1913 &id->p_encoder->fmt_in );
1914 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_vf2 );
1915 p_fmt_out = filter_chain_GetFmtOut( id->p_uf_chain );
1916 es_format_Copy( &id->p_encoder->fmt_in, p_fmt_out );
1917 id->p_encoder->fmt_out.video.i_width =
1918 id->p_encoder->fmt_in.video.i_width;
1919 id->p_encoder->fmt_out.video.i_height =
1920 id->p_encoder->fmt_in.video.i_height;
1921 id->p_encoder->fmt_out.video.i_aspect =
1922 id->p_encoder->fmt_in.video.i_aspect;
1925 if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS )
1927 p_pic->pf_release( p_pic );
1928 transcode_video_close( p_stream, id );
1929 id->b_transcode = false;
1930 return VLC_EGENERIC;
1934 /* Run filter chain */
1936 p_pic = filter_chain_VideoFilter( id->p_f_chain, p_pic );
1942 /* Check if we have a subpicture to overlay */
1945 p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date,
1946 false /* Fixme: check if stream is paused */, false );
1947 /* TODO: get another pic */
1950 /* Overlay subpicture */
1955 if( p_pic->i_refcount && !filter_chain_GetLength( id->p_f_chain ) )
1957 /* We can't modify the picture, we need to duplicate it */
1958 picture_t *p_tmp = video_new_buffer_decoder( id->p_decoder );
1961 picture_Copy( p_tmp, p_pic );
1962 p_pic->pf_release( p_pic );
1967 if( filter_chain_GetLength( id->p_f_chain ) > 0 )
1968 fmt = filter_chain_GetFmtOut( id->p_f_chain )->video;
1970 fmt = id->p_decoder->fmt_out.video;
1972 /* FIXME (shouldn't have to be done here) */
1973 fmt.i_sar_num = fmt.i_aspect * fmt.i_height / fmt.i_width;
1974 fmt.i_sar_den = VOUT_ASPECT_FACTOR;
1976 spu_RenderSubpictures( p_sys->p_spu, p_pic, &fmt,
1977 p_subpic, &id->p_decoder->fmt_out.video, false );
1980 /* Run user specified filter chain */
1981 if( id->p_uf_chain )
1982 p_pic = filter_chain_VideoFilter( id->p_uf_chain, p_pic );
1984 if( p_sys->i_threads == 0 )
1988 video_timer_start( id->p_encoder );
1989 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
1990 video_timer_stop( id->p_encoder );
1992 block_ChainAppend( out, p_block );
1995 if( p_sys->b_master_sync )
1997 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
1998 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1999 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
2001 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2002 date_Set( &id->interpolated_pts, p_pic->date );
2003 i_pts = p_pic->date + 1;
2005 date_Increment( &id->interpolated_pts, 1 );
2008 if( p_sys->b_master_sync && i_duplicate > 1 )
2010 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
2011 if( (p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT)
2012 || ((p_pic->date - i_pts) < -MASTER_SYNC_MAX_DRIFT) )
2014 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2015 date_Set( &id->interpolated_pts, p_pic->date );
2016 i_pts = p_pic->date + 1;
2018 date_Increment( &id->interpolated_pts, 1 );
2020 if( p_sys->i_threads >= 1 )
2022 /* We can't modify the picture, we need to duplicate it */
2023 p_pic2 = video_new_buffer_decoder( id->p_decoder );
2024 if( p_pic2 != NULL )
2026 picture_Copy( p_pic2, p_pic );
2027 p_pic2->date = i_pts;
2033 p_pic->date = i_pts;
2034 video_timer_start( id->p_encoder );
2035 p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);
2036 video_timer_stop( id->p_encoder );
2037 block_ChainAppend( out, p_block );
2041 if( p_sys->i_threads == 0 )
2043 p_pic->pf_release( p_pic );
2047 vlc_mutex_lock( &p_sys->lock_out );
2048 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
2049 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2050 *out = p_sys->p_buffers;
2051 p_sys->p_buffers = NULL;
2052 if( p_pic2 != NULL )
2054 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic2;
2055 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2057 vlc_cond_signal( &p_sys->cond );
2058 vlc_mutex_unlock( &p_sys->lock_out );
2065 static void* EncoderThread( vlc_object_t* p_this )
2067 sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_this;
2068 sout_stream_id_t *id = p_sys->id_video;
2070 int canc = vlc_savecancel ();
2072 while( vlc_object_alive (p_sys) && !p_sys->b_error )
2076 vlc_mutex_lock( &p_sys->lock_out );
2077 while( p_sys->i_last_pic == p_sys->i_first_pic )
2079 vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );
2080 if( !vlc_object_alive (p_sys) || p_sys->b_error ) break;
2082 if( !vlc_object_alive (p_sys) || p_sys->b_error )
2084 vlc_mutex_unlock( &p_sys->lock_out );
2088 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2089 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2090 vlc_mutex_unlock( &p_sys->lock_out );
2092 video_timer_start( id->p_encoder );
2093 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2094 video_timer_stop( id->p_encoder );
2096 vlc_mutex_lock( &p_sys->lock_out );
2097 block_ChainAppend( &p_sys->p_buffers, p_block );
2099 vlc_mutex_unlock( &p_sys->lock_out );
2100 p_pic->pf_release( p_pic );
2103 while( p_sys->i_last_pic != p_sys->i_first_pic )
2105 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2106 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2107 p_pic->pf_release( p_pic );
2109 block_ChainRelease( p_sys->p_buffers );
2111 vlc_restorecancel (canc);
2115 struct picture_sys_t
2117 vlc_object_t *p_owner;
2120 static void video_release_buffer( picture_t *p_pic )
2122 if( p_pic && !p_pic->i_refcount && p_pic->pf_release && p_pic->p_sys )
2124 video_del_buffer_decoder( (decoder_t *)p_pic->p_sys->p_owner, p_pic );
2126 else if( p_pic && p_pic->i_refcount > 0 ) p_pic->i_refcount--;
2129 static picture_t *video_new_buffer( vlc_object_t *p_this, picture_t **pp_ring,
2130 sout_stream_sys_t *p_sys )
2132 decoder_t *p_dec = (decoder_t *)p_this;
2136 /* Find an empty space in the picture ring buffer */
2137 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2139 if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2141 pp_ring[i]->i_status = RESERVED_PICTURE;
2145 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2147 if( pp_ring[i] == 0 ) break;
2150 if( i == PICTURE_RING_SIZE && p_sys->i_threads >= 1 )
2152 int i_first_pic = p_sys->i_first_pic;
2154 if( p_sys->i_first_pic != p_sys->i_last_pic )
2156 /* Encoder still has stuff to encode, wait to clear-up the list */
2157 while( p_sys->i_first_pic == i_first_pic )
2161 /* Find an empty space in the picture ring buffer */
2162 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2164 if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2166 pp_ring[i]->i_status = RESERVED_PICTURE;
2170 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2172 if( pp_ring[i] == 0 ) break;
2176 if( i == PICTURE_RING_SIZE )
2178 msg_Err( p_this, "decoder/filter is leaking pictures, "
2179 "resetting its ring buffer" );
2181 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2183 pp_ring[i]->pf_release( pp_ring[i] );
2189 p_pic = picture_New( p_dec->fmt_out.video.i_chroma,
2190 p_dec->fmt_out.video.i_width,
2191 p_dec->fmt_out.video.i_height,
2192 p_dec->fmt_out.video.i_aspect );
2193 if( !p_pic ) return NULL;
2194 p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
2195 p_pic->p_sys = calloc( 1, sizeof(picture_sys_t) );
2198 picture_Release( p_pic );
2201 p_pic->pf_release = video_release_buffer;
2202 p_pic->i_refcount = 0;
2208 static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
2210 return video_new_buffer( VLC_OBJECT(p_dec),
2211 p_dec->p_owner->pp_pics, p_dec->p_owner->p_sys );
2214 static picture_t *video_new_buffer_filter( filter_t *p_filter )
2216 return video_new_buffer( VLC_OBJECT(p_filter),
2217 p_filter->p_owner->pp_pics,
2218 p_filter->p_owner->p_sys );
2221 static void video_del_buffer( vlc_object_t *p_this, picture_t *p_pic )
2227 free( p_pic->p_data_orig );
2228 free( p_pic->p_sys );
2233 static void video_del_buffer_decoder( decoder_t *p_decoder, picture_t *p_pic )
2235 VLC_UNUSED(p_decoder);
2236 p_pic->i_refcount = 0;
2237 p_pic->i_status = DESTROYED_PICTURE;
2238 picture_CleanupQuant( p_pic );
2241 static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic )
2243 VLC_UNUSED(p_filter);
2244 p_pic->i_refcount = 0;
2245 p_pic->i_status = DESTROYED_PICTURE;
2246 picture_CleanupQuant( p_pic );
2249 static void video_link_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2252 p_pic->i_refcount++;
2255 static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2258 video_release_buffer( p_pic );
2264 static subpicture_t *spu_new_buffer( decoder_t * );
2265 static void spu_del_buffer( decoder_t *, subpicture_t * );
2267 static int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2269 sout_stream_sys_t *p_sys = p_stream->p_sys;
2275 /* Initialization of decoder structures */
2276 id->p_decoder->pf_decode_sub = NULL;
2277 id->p_decoder->pf_spu_buffer_new = spu_new_buffer;
2278 id->p_decoder->pf_spu_buffer_del = spu_del_buffer;
2279 id->p_decoder->p_owner = (decoder_owner_sys_t *)p_stream;
2280 /* id->p_decoder->p_cfg = p_sys->p_spu_cfg; */
2282 id->p_decoder->p_module =
2283 module_need( id->p_decoder, "decoder", "$codec", 0 );
2285 if( !id->p_decoder->p_module )
2287 msg_Err( p_stream, "cannot find spu decoder" );
2288 return VLC_EGENERIC;
2291 if( !p_sys->b_soverlay )
2294 /* Initialization of encoder format structures */
2295 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2296 id->p_decoder->fmt_in.i_codec );
2298 id->p_encoder->p_cfg = p_sys->p_spu_cfg;
2300 id->p_encoder->p_module =
2301 module_need( id->p_encoder, "encoder", p_sys->psz_senc, true );
2303 if( !id->p_encoder->p_module )
2305 module_unneed( id->p_decoder, id->p_decoder->p_module );
2306 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_senc );
2307 return VLC_EGENERIC;
2313 p_sys->p_spu = spu_Create( p_stream );
2314 spu_Init( p_sys->p_spu );
2320 static void transcode_spu_close( sout_stream_id_t *id)
2323 if( id->p_decoder->p_module )
2324 module_unneed( id->p_decoder, id->p_decoder->p_module );
2325 if( id->p_decoder->p_description )
2326 vlc_meta_Delete( id->p_decoder->p_description );
2329 if( id->p_encoder->p_module )
2330 module_unneed( id->p_encoder, id->p_encoder->p_module );
2333 static int transcode_spu_process( sout_stream_t *p_stream,
2334 sout_stream_id_t *id,
2335 block_t *in, block_t **out )
2337 sout_stream_sys_t *p_sys = p_stream->p_sys;
2338 subpicture_t *p_subpic;
2341 p_subpic = id->p_decoder->pf_decode_sub( id->p_decoder, &in );
2343 return VLC_EGENERIC;
2345 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_SUBTITLE, 1 );
2347 if( p_sys->b_master_sync && p_sys->i_master_drift )
2349 p_subpic->i_start -= p_sys->i_master_drift;
2350 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2353 if( p_sys->b_soverlay )
2355 spu_DisplaySubpicture( p_sys->p_spu, p_subpic );
2361 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2362 spu_del_buffer( id->p_decoder, p_subpic );
2365 block_ChainAppend( out, p_block );
2370 return VLC_EGENERIC;
2373 static subpicture_t *spu_new_buffer( decoder_t *p_dec )
2375 VLC_UNUSED( p_dec );
2376 return subpicture_New();
2379 static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
2381 VLC_UNUSED( p_dec );
2382 subpicture_Delete( p_subpic );
2388 static int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2390 sout_stream_sys_t *p_sys = p_stream->p_sys;
2392 id->p_decoder->fmt_in.i_cat = SPU_ES;
2393 id->p_encoder->fmt_out.psz_language = strdup( "osd" );
2395 if( p_sys->i_osdcodec != 0 || p_sys->psz_osdenc )
2397 msg_Dbg( p_stream, "creating osdmenu transcoding from fcc=`%4.4s' "
2398 "to fcc=`%4.4s'", (char*)&id->p_encoder->fmt_out.i_codec,
2399 (char*)&p_sys->i_osdcodec );
2401 /* Complete destination format */
2402 id->p_encoder->fmt_out.i_codec = p_sys->i_osdcodec;
2405 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2406 VLC_FOURCC('Y','U','V','A') );
2407 id->p_encoder->fmt_in.psz_language = strdup( "osd" );
2409 id->p_encoder->p_cfg = p_sys->p_osd_cfg;
2411 id->p_encoder->p_module =
2412 module_need( id->p_encoder, "encoder", p_sys->psz_osdenc, true );
2414 if( !id->p_encoder->p_module )
2416 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_osdenc );
2420 /* open output stream */
2421 id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_encoder->fmt_out );
2422 id->b_transcode = true;
2424 if( !id->id ) goto error;
2428 msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
2429 (char*)&id->p_decoder->fmt_out.i_codec );
2430 id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_decoder->fmt_out );
2431 id->b_transcode = false;
2433 if( !id->id ) goto error;
2438 p_sys->p_spu = spu_Create( p_stream );
2439 spu_Init( p_sys->p_spu );
2445 msg_Err( p_stream, "starting osd encoding thread failed" );
2446 if( id->p_encoder->p_module )
2447 module_unneed( id->p_encoder, id->p_encoder->p_module );
2448 p_sys->b_osd = false;
2449 return VLC_EGENERIC;
2452 static void transcode_osd_close( sout_stream_t *p_stream, sout_stream_id_t *id)
2454 sout_stream_sys_t *p_sys = p_stream->p_sys;
2459 if( id->p_encoder->p_module )
2460 module_unneed( id->p_encoder, id->p_encoder->p_module );
2462 p_sys->b_osd = false;
2465 static int transcode_osd_process( sout_stream_t *p_stream,
2466 sout_stream_id_t *id,
2467 block_t *in, block_t **out )
2469 sout_stream_sys_t *p_sys = p_stream->p_sys;
2470 subpicture_t *p_subpic = NULL;
2472 /* Check if we have a subpicture to send */
2473 if( p_sys->p_spu && in->i_dts > 0)
2475 p_subpic = spu_SortSubpictures( p_sys->p_spu, in->i_dts, false, false );
2479 msg_Warn( p_stream, "spu channel not initialized, doing it now" );
2482 p_sys->p_spu = spu_Create( p_stream );
2483 spu_Init( p_sys->p_spu );
2489 block_t *p_block = NULL;
2491 if( p_sys->b_master_sync && p_sys->i_master_drift )
2493 p_subpic->i_start -= p_sys->i_master_drift;
2494 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2497 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2498 subpicture_Delete( p_subpic );
2501 p_block->i_dts = p_block->i_pts = in->i_dts;
2502 block_ChainAppend( out, p_block );
2506 return VLC_EGENERIC;