1 /*****************************************************************************
2 * transcode.c: transcoding stream output module
3 *****************************************************************************
4 * Copyright (C) 2003-2008 the VideoLAN team
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8 * Gildas Bazin <gbazin@videolan.org>
9 * Jean-Paul Saman <jpsaman #_at_# m2x dot nl>
10 * Antoine Cellerier <dionoea at videolan dot org>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25 *****************************************************************************/
27 /*****************************************************************************
29 *****************************************************************************/
34 #include <vlc_common.h>
35 #include <vlc_plugin.h>
36 #include <vlc_input.h>
40 #include <vlc_codec.h>
41 #include <vlc_block.h>
42 #include <vlc_filter.h>
47 #define MASTER_SYNC_MAX_DRIFT 100000
51 /*****************************************************************************
53 *****************************************************************************/
54 #define VENC_TEXT N_("Video encoder")
55 #define VENC_LONGTEXT N_( \
56 "This is the video encoder module that will be used (and its associated "\
58 #define VCODEC_TEXT N_("Destination video codec")
59 #define VCODEC_LONGTEXT N_( \
60 "This is the video codec that will be used.")
61 #define VB_TEXT N_("Video bitrate")
62 #define VB_LONGTEXT N_( \
63 "Target bitrate of the transcoded video stream." )
64 #define SCALE_TEXT N_("Video scaling")
65 #define SCALE_LONGTEXT N_( \
66 "Scale factor to apply to the video while transcoding (eg: 0.25)")
67 #define FPS_TEXT N_("Video frame-rate")
68 #define FPS_LONGTEXT N_( \
69 "Target output frame rate for the video stream." )
70 #define DEINTERLACE_TEXT N_("Deinterlace video")
71 #define DEINTERLACE_LONGTEXT N_( \
72 "Deinterlace the video before encoding." )
73 #define DEINTERLACE_MODULE_TEXT N_("Deinterlace module")
74 #define DEINTERLACE_MODULE_LONGTEXT N_( \
75 "Specify the deinterlace module to use." )
76 #define WIDTH_TEXT N_("Video width")
77 #define WIDTH_LONGTEXT N_( \
78 "Output video width." )
79 #define HEIGHT_TEXT N_("Video height")
80 #define HEIGHT_LONGTEXT N_( \
81 "Output video height." )
82 #define MAXWIDTH_TEXT N_("Maximum video width")
83 #define MAXWIDTH_LONGTEXT N_( \
84 "Maximum output video width." )
85 #define MAXHEIGHT_TEXT N_("Maximum video height")
86 #define MAXHEIGHT_LONGTEXT N_( \
87 "Maximum output video height." )
88 #define VFILTER_TEXT N_("Video filter")
89 #define VFILTER_LONGTEXT N_( \
90 "Video filters will be applied to the video streams (after overlays " \
91 "are applied). You must enter a comma-separated list of filters." )
93 #define AENC_TEXT N_("Audio encoder")
94 #define AENC_LONGTEXT N_( \
95 "This is the audio encoder module that will be used (and its associated "\
97 #define ACODEC_TEXT N_("Destination audio codec")
98 #define ACODEC_LONGTEXT N_( \
99 "This is the audio codec that will be used.")
100 #define AB_TEXT N_("Audio bitrate")
101 #define AB_LONGTEXT N_( \
102 "Target bitrate of the transcoded audio stream." )
103 #define ARATE_TEXT N_("Audio sample rate")
104 #define ARATE_LONGTEXT N_( \
105 "Sample rate of the transcoded audio stream (11250, 22500, 44100 or 48000).")
106 #define ACHANS_TEXT N_("Audio channels")
107 #define ACHANS_LONGTEXT N_( \
108 "Number of audio channels in the transcoded streams." )
109 #define AFILTER_TEXT N_("Audio filter")
110 #define AFILTER_LONGTEXT N_( \
111 "Audio filters will be applied to the audio streams (after conversion " \
112 "filters are applied). You must enter a comma-separated list of filters." )
114 #define SENC_TEXT N_("Subtitles encoder")
115 #define SENC_LONGTEXT N_( \
116 "This is the subtitles encoder module that will be used (and its " \
117 "associated options)." )
118 #define SCODEC_TEXT N_("Destination subtitles codec")
119 #define SCODEC_LONGTEXT N_( \
120 "This is the subtitles codec that will be used." )
122 #define SFILTER_TEXT N_("Overlays")
123 #define SFILTER_LONGTEXT N_( \
124 "This allows you to add overlays (also known as \"subpictures\" on the "\
125 "transcoded video stream. The subpictures produced by the filters will "\
126 "be overlayed directly onto the video. You must specify a comma-separated "\
127 "list of subpicture modules" )
129 #define OSD_TEXT N_("OSD menu")
130 #define OSD_LONGTEXT N_(\
131 "Stream the On Screen Display menu (using the osdmenu subpicture module)." )
133 #define THREADS_TEXT N_("Number of threads")
134 #define THREADS_LONGTEXT N_( \
135 "Number of threads used for the transcoding." )
136 #define HP_TEXT N_("High priority")
137 #define HP_LONGTEXT N_( \
138 "Runs the optional encoder thread at the OUTPUT priority instead of " \
141 #define ASYNC_TEXT N_("Synchronise on audio track")
142 #define ASYNC_LONGTEXT N_( \
143 "This option will drop/duplicate video frames to synchronise the video " \
144 "track on the audio track." )
146 #define HURRYUP_TEXT N_( "Hurry up" )
147 #define HURRYUP_LONGTEXT N_( "The transcoder will drop frames if your CPU " \
148 "can't keep up with the encoding rate." )
150 static const char *const ppsz_deinterlace_type[] =
152 "deinterlace", "ffmpeg-deinterlace"
155 static int Open ( vlc_object_t * );
156 static void Close( vlc_object_t * );
158 #define SOUT_CFG_PREFIX "sout-transcode-"
161 set_shortname( N_("Transcode"));
162 set_description( N_("Transcode stream output") );
163 set_capability( "sout stream", 50 );
164 add_shortcut( "transcode" );
165 set_callbacks( Open, Close );
166 set_category( CAT_SOUT );
167 set_subcategory( SUBCAT_SOUT_STREAM );
168 set_section( N_("Video"), NULL );
169 add_string( SOUT_CFG_PREFIX "venc", NULL, NULL, VENC_TEXT,
170 VENC_LONGTEXT, false );
171 add_string( SOUT_CFG_PREFIX "vcodec", NULL, NULL, VCODEC_TEXT,
172 VCODEC_LONGTEXT, false );
173 add_integer( SOUT_CFG_PREFIX "vb", 800 * 1000, NULL, VB_TEXT,
174 VB_LONGTEXT, false );
175 add_float( SOUT_CFG_PREFIX "scale", 1, NULL, SCALE_TEXT,
176 SCALE_LONGTEXT, false );
177 add_float( SOUT_CFG_PREFIX "fps", 0, NULL, FPS_TEXT,
178 FPS_LONGTEXT, false );
179 add_bool( SOUT_CFG_PREFIX "hurry-up", true, NULL, HURRYUP_TEXT,
180 HURRYUP_LONGTEXT, false );
181 add_bool( SOUT_CFG_PREFIX "deinterlace", 0, NULL, DEINTERLACE_TEXT,
182 DEINTERLACE_LONGTEXT, false );
183 add_string( SOUT_CFG_PREFIX "deinterlace-module", "deinterlace", NULL,
184 DEINTERLACE_MODULE_TEXT, DEINTERLACE_MODULE_LONGTEXT,
186 change_string_list( ppsz_deinterlace_type, 0, 0 );
187 add_integer( SOUT_CFG_PREFIX "width", 0, NULL, WIDTH_TEXT,
188 WIDTH_LONGTEXT, true );
189 add_integer( SOUT_CFG_PREFIX "height", 0, NULL, HEIGHT_TEXT,
190 HEIGHT_LONGTEXT, true );
191 add_integer( SOUT_CFG_PREFIX "maxwidth", 0, NULL, MAXWIDTH_TEXT,
192 MAXWIDTH_LONGTEXT, true );
193 add_integer( SOUT_CFG_PREFIX "maxheight", 0, NULL, MAXHEIGHT_TEXT,
194 MAXHEIGHT_LONGTEXT, true );
195 add_module_list( SOUT_CFG_PREFIX "vfilter", "video filter2",
197 VFILTER_TEXT, VFILTER_LONGTEXT, false );
199 set_section( N_("Audio"), NULL );
200 add_string( SOUT_CFG_PREFIX "aenc", NULL, NULL, AENC_TEXT,
201 AENC_LONGTEXT, false );
202 add_string( SOUT_CFG_PREFIX "acodec", NULL, NULL, ACODEC_TEXT,
203 ACODEC_LONGTEXT, false );
204 add_integer( SOUT_CFG_PREFIX "ab", 0, NULL, AB_TEXT,
205 AB_LONGTEXT, false );
206 add_integer( SOUT_CFG_PREFIX "channels", 0, NULL, ACHANS_TEXT,
207 ACHANS_LONGTEXT, false );
208 add_integer( SOUT_CFG_PREFIX "samplerate", 0, NULL, ARATE_TEXT,
209 ARATE_LONGTEXT, true );
210 add_bool( SOUT_CFG_PREFIX "audio-sync", 0, NULL, ASYNC_TEXT,
211 ASYNC_LONGTEXT, false );
212 add_module_list( SOUT_CFG_PREFIX "afilter", "audio filter2",
214 AFILTER_TEXT, AFILTER_LONGTEXT, false );
216 set_section( N_("Overlays/Subtitles"), NULL );
217 add_string( SOUT_CFG_PREFIX "senc", NULL, NULL, SENC_TEXT,
218 SENC_LONGTEXT, false );
219 add_string( SOUT_CFG_PREFIX "scodec", NULL, NULL, SCODEC_TEXT,
220 SCODEC_LONGTEXT, false );
221 add_bool( SOUT_CFG_PREFIX "soverlay", 0, NULL, SCODEC_TEXT,
222 SCODEC_LONGTEXT, false );
223 add_module_list( SOUT_CFG_PREFIX "sfilter", "video filter",
225 SFILTER_TEXT, SFILTER_LONGTEXT, false );
227 set_section( N_("On Screen Display"), NULL );
228 add_bool( SOUT_CFG_PREFIX "osd", 0, NULL, OSD_TEXT,
229 OSD_LONGTEXT, false );
231 set_section( N_("Miscellaneous"), NULL );
232 add_integer( SOUT_CFG_PREFIX "threads", 0, NULL, THREADS_TEXT,
233 THREADS_LONGTEXT, true );
234 add_bool( SOUT_CFG_PREFIX "high-priority", 0, NULL, HP_TEXT, HP_LONGTEXT,
239 static const char *const ppsz_sout_options[] = {
240 "venc", "vcodec", "vb",
241 "scale", "fps", "width", "height", "vfilter", "deinterlace",
242 "deinterlace-module", "threads", "hurry-up", "aenc", "acodec", "ab",
243 "afilter", "samplerate", "channels", "senc", "scodec", "soverlay",
244 "sfilter", "osd", "audio-sync", "high-priority", "maxwidth", "maxheight",
248 /*****************************************************************************
249 * Exported prototypes
250 *****************************************************************************/
251 static sout_stream_id_t *Add ( sout_stream_t *, es_format_t * );
252 static int Del ( sout_stream_t *, sout_stream_id_t * );
253 static int Send( sout_stream_t *, sout_stream_id_t *, block_t* );
255 static int transcode_audio_new ( sout_stream_t *, sout_stream_id_t * );
256 static void transcode_audio_close ( sout_stream_id_t * );
257 static int transcode_audio_process( sout_stream_t *, sout_stream_id_t *,
258 block_t *, block_t ** );
260 static aout_buffer_t *audio_new_buffer( decoder_t *, int );
261 static void audio_del_buffer( decoder_t *, aout_buffer_t * );
263 static int transcode_video_new ( sout_stream_t *, sout_stream_id_t * );
264 static void transcode_video_close ( sout_stream_t *, sout_stream_id_t * );
265 static void transcode_video_encoder_init( sout_stream_t *, sout_stream_id_t *);
266 static int transcode_video_encoder_open( sout_stream_t *, sout_stream_id_t *);
267 static int transcode_video_process( sout_stream_t *, sout_stream_id_t *,
268 block_t *, block_t ** );
270 static void video_del_buffer( vlc_object_t *, picture_t * );
271 static picture_t *video_new_buffer_decoder( decoder_t * );
272 static void video_del_buffer_decoder( decoder_t *, picture_t * );
273 static void video_link_picture_decoder( decoder_t *, picture_t * );
274 static void video_unlink_picture_decoder( decoder_t *, picture_t * );
275 static picture_t *video_new_buffer_filter( filter_t * );
276 static void video_del_buffer_filter( filter_t *, picture_t * );
278 static int transcode_spu_new ( sout_stream_t *, sout_stream_id_t * );
279 static void transcode_spu_close ( sout_stream_id_t * );
280 static int transcode_spu_process( sout_stream_t *, sout_stream_id_t *,
281 block_t *, block_t ** );
283 static int transcode_osd_new ( sout_stream_t *, sout_stream_id_t * );
284 static void transcode_osd_close ( sout_stream_t *, sout_stream_id_t * );
285 static int transcode_osd_process( sout_stream_t *, sout_stream_id_t *,
286 block_t *, block_t ** );
288 static void* EncoderThread( vlc_object_t * p_this );
290 static const int pi_channels_maps[6] =
293 AOUT_CHAN_CENTER, AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
294 AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
295 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
296 | AOUT_CHAN_REARRIGHT,
297 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
298 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
301 #define PICTURE_RING_SIZE 64
302 #define SUBPICTURE_RING_SIZE 20
304 #define ENC_FRAMERATE (25 * 1000 + .5)
305 #define ENC_FRAMERATE_BASE 1000
307 struct sout_stream_sys_t
311 sout_stream_t *p_out;
312 sout_stream_id_t *id_video;
314 vlc_mutex_t lock_out;
316 picture_t * pp_pics[PICTURE_RING_SIZE];
317 int i_first_pic, i_last_pic;
320 vlc_fourcc_t i_acodec; /* codec audio (0 if not transcode) */
322 config_chain_t *p_audio_cfg;
323 uint32_t i_sample_rate;
330 vlc_fourcc_t i_vcodec; /* codec video (0 if not transcode) */
332 config_chain_t *p_video_cfg;
336 unsigned int i_width, i_maxwidth;
337 unsigned int i_height, i_maxheight;
339 char *psz_deinterlace;
340 config_chain_t *p_deinterlace_cfg;
342 bool b_high_priority;
348 vlc_fourcc_t i_scodec; /* codec spu (0 if not transcode) */
351 config_chain_t *p_spu_cfg;
355 vlc_fourcc_t i_osdcodec; /* codec osd menu (0 if not transcode) */
357 config_chain_t *p_osd_cfg;
358 bool b_osd; /* true when osd es is registered */
362 mtime_t i_master_drift;
365 struct decoder_owner_sys_t
367 picture_t *pp_pics[PICTURE_RING_SIZE];
368 sout_stream_sys_t *p_sys;
370 struct filter_owner_sys_t
372 picture_t *pp_pics[PICTURE_RING_SIZE];
373 sout_stream_sys_t *p_sys;
376 /*****************************************************************************
378 *****************************************************************************/
379 static int Open( vlc_object_t *p_this )
381 sout_stream_t *p_stream = (sout_stream_t*)p_this;
382 sout_stream_sys_t *p_sys;
385 p_sys = vlc_object_create( p_this, sizeof( sout_stream_sys_t ) );
387 p_sys->p_out = sout_StreamNew( p_stream->p_sout, p_stream->psz_next );
390 msg_Err( p_stream, "cannot create chain" );
391 vlc_object_release( p_sys );
395 p_sys->i_master_drift = 0;
397 config_ChainParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options,
400 /* Audio transcoding parameters */
401 var_Get( p_stream, SOUT_CFG_PREFIX "aenc", &val );
402 p_sys->psz_aenc = NULL;
403 p_sys->p_audio_cfg = NULL;
404 if( val.psz_string && *val.psz_string )
407 psz_next = config_ChainCreate( &p_sys->psz_aenc, &p_sys->p_audio_cfg,
411 free( val.psz_string );
413 var_Get( p_stream, SOUT_CFG_PREFIX "acodec", &val );
415 if( val.psz_string && *val.psz_string )
418 memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) );
419 p_sys->i_acodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
421 free( val.psz_string );
423 var_Get( p_stream, SOUT_CFG_PREFIX "ab", &val );
424 p_sys->i_abitrate = val.i_int;
425 if( p_sys->i_abitrate < 4000 ) p_sys->i_abitrate *= 1000;
427 var_Get( p_stream, SOUT_CFG_PREFIX "samplerate", &val );
428 p_sys->i_sample_rate = val.i_int;
430 var_Get( p_stream, SOUT_CFG_PREFIX "channels", &val );
431 p_sys->i_channels = val.i_int;
433 if( p_sys->i_acodec )
435 if( p_sys->i_acodec == VLC_FOURCC('m','p','3',0) &&
436 p_sys->i_channels > 2 )
438 msg_Warn( p_stream, "%d channels invalid for mp3, forcing to 2",
440 p_sys->i_channels = 2;
442 msg_Dbg( p_stream, "codec audio=%4.4s %dHz %d channels %dKb/s",
443 (char *)&p_sys->i_acodec, p_sys->i_sample_rate,
444 p_sys->i_channels, p_sys->i_abitrate / 1000 );
447 var_Get( p_stream, SOUT_CFG_PREFIX "afilter", &val );
448 if( val.psz_string && *val.psz_string )
449 p_sys->psz_af2 = val.psz_string;
452 free( val.psz_string );
453 p_sys->psz_af2 = NULL;
456 /* Video transcoding parameters */
457 var_Get( p_stream, SOUT_CFG_PREFIX "venc", &val );
458 p_sys->psz_venc = NULL;
459 p_sys->p_video_cfg = NULL;
460 if( val.psz_string && *val.psz_string )
463 psz_next = config_ChainCreate( &p_sys->psz_venc, &p_sys->p_video_cfg,
467 free( val.psz_string );
469 var_Get( p_stream, SOUT_CFG_PREFIX "vcodec", &val );
471 if( val.psz_string && *val.psz_string )
474 memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) );
475 p_sys->i_vcodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
477 free( val.psz_string );
479 var_Get( p_stream, SOUT_CFG_PREFIX "vb", &val );
480 p_sys->i_vbitrate = val.i_int;
481 if( p_sys->i_vbitrate < 16000 ) p_sys->i_vbitrate *= 1000;
483 var_Get( p_stream, SOUT_CFG_PREFIX "scale", &val );
484 p_sys->f_scale = val.f_float;
486 var_Get( p_stream, SOUT_CFG_PREFIX "fps", &val );
487 p_sys->f_fps = val.f_float;
489 var_Get( p_stream, SOUT_CFG_PREFIX "hurry-up", &val );
490 p_sys->b_hurry_up = val.b_bool;
492 var_Get( p_stream, SOUT_CFG_PREFIX "width", &val );
493 p_sys->i_width = val.i_int;
495 var_Get( p_stream, SOUT_CFG_PREFIX "height", &val );
496 p_sys->i_height = val.i_int;
498 var_Get( p_stream, SOUT_CFG_PREFIX "maxwidth", &val );
499 p_sys->i_maxwidth = val.i_int;
501 var_Get( p_stream, SOUT_CFG_PREFIX "maxheight", &val );
502 p_sys->i_maxheight = val.i_int;
504 var_Get( p_stream, SOUT_CFG_PREFIX "vfilter", &val );
505 if( val.psz_string && *val.psz_string )
506 p_sys->psz_vf2 = val.psz_string;
509 free( val.psz_string );
510 p_sys->psz_vf2 = NULL;
513 var_Get( p_stream, SOUT_CFG_PREFIX "deinterlace", &val );
514 p_sys->b_deinterlace = val.b_bool;
516 var_Get( p_stream, SOUT_CFG_PREFIX "deinterlace-module", &val );
517 p_sys->psz_deinterlace = NULL;
518 p_sys->p_deinterlace_cfg = NULL;
519 if( val.psz_string && *val.psz_string )
522 psz_next = config_ChainCreate( &p_sys->psz_deinterlace,
523 &p_sys->p_deinterlace_cfg,
527 free( val.psz_string );
529 var_Get( p_stream, SOUT_CFG_PREFIX "threads", &val );
530 p_sys->i_threads = val.i_int;
531 var_Get( p_stream, SOUT_CFG_PREFIX "high-priority", &val );
532 p_sys->b_high_priority = val.b_bool;
534 if( p_sys->i_vcodec )
536 msg_Dbg( p_stream, "codec video=%4.4s %dx%d scaling: %f %dkb/s",
537 (char *)&p_sys->i_vcodec, p_sys->i_width, p_sys->i_height,
538 p_sys->f_scale, p_sys->i_vbitrate / 1000 );
541 /* Subpictures transcoding parameters */
543 p_sys->psz_senc = NULL;
544 p_sys->p_spu_cfg = NULL;
547 var_Get( p_stream, SOUT_CFG_PREFIX "senc", &val );
548 if( val.psz_string && *val.psz_string )
551 psz_next = config_ChainCreate( &p_sys->psz_senc, &p_sys->p_spu_cfg,
555 free( val.psz_string );
557 var_Get( p_stream, SOUT_CFG_PREFIX "scodec", &val );
558 if( val.psz_string && *val.psz_string )
561 memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) );
562 p_sys->i_scodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
564 free( val.psz_string );
566 if( p_sys->i_scodec )
568 msg_Dbg( p_stream, "codec spu=%4.4s", (char *)&p_sys->i_scodec );
571 var_Get( p_stream, SOUT_CFG_PREFIX "soverlay", &val );
572 p_sys->b_soverlay = val.b_bool;
574 var_Get( p_stream, SOUT_CFG_PREFIX "sfilter", &val );
575 if( val.psz_string && *val.psz_string )
577 p_sys->p_spu = spu_Create( p_stream );
578 var_Create( p_sys->p_spu, "sub-filter", VLC_VAR_STRING );
579 var_Set( p_sys->p_spu, "sub-filter", val );
580 spu_Init( p_sys->p_spu );
582 free( val.psz_string );
584 /* OSD menu transcoding parameters */
585 p_sys->psz_osdenc = NULL;
586 p_sys->p_osd_cfg = NULL;
587 p_sys->i_osdcodec = 0;
588 p_sys->b_osd = false;
590 var_Get( p_stream, SOUT_CFG_PREFIX "osd", &val );
596 psz_next = config_ChainCreate( &p_sys->psz_osdenc,
597 &p_sys->p_osd_cfg, strdup( "dvbsub") );
600 p_sys->i_osdcodec = VLC_FOURCC('Y','U','V','P' );
602 msg_Dbg( p_stream, "codec osd=%4.4s", (char *)&p_sys->i_osdcodec );
606 osd_val.psz_string = strdup("osdmenu");
607 p_sys->p_spu = spu_Create( p_stream );
608 var_Create( p_sys->p_spu, "sub-filter", VLC_VAR_STRING );
609 var_Set( p_sys->p_spu, "sub-filter", osd_val );
610 spu_Init( p_sys->p_spu );
611 free( osd_val.psz_string );
615 osd_val.psz_string = strdup("osdmenu");
616 var_Set( p_sys->p_spu, "sub-filter", osd_val );
617 free( osd_val.psz_string );
622 var_Get( p_stream, SOUT_CFG_PREFIX "audio-sync", &val );
623 p_sys->b_master_sync = val.b_bool;
624 if( p_sys->f_fps > 0 ) p_sys->b_master_sync = true;
626 p_stream->pf_add = Add;
627 p_stream->pf_del = Del;
628 p_stream->pf_send = Send;
629 p_stream->p_sys = p_sys;
634 /*****************************************************************************
636 *****************************************************************************/
637 static void Close( vlc_object_t * p_this )
639 sout_stream_t *p_stream = (sout_stream_t*)p_this;
640 sout_stream_sys_t *p_sys = p_stream->p_sys;
642 sout_StreamDelete( p_sys->p_out );
644 free( p_sys->psz_af2 );
646 while( p_sys->p_audio_cfg != NULL )
648 config_chain_t *p_next = p_sys->p_audio_cfg->p_next;
650 free( p_sys->p_audio_cfg->psz_name );
651 free( p_sys->p_audio_cfg->psz_value );
652 free( p_sys->p_audio_cfg );
654 p_sys->p_audio_cfg = p_next;
656 free( p_sys->psz_aenc );
658 free( p_sys->psz_vf2 );
660 while( p_sys->p_video_cfg != NULL )
662 config_chain_t *p_next = p_sys->p_video_cfg->p_next;
664 free( p_sys->p_video_cfg->psz_name );
665 free( p_sys->p_video_cfg->psz_value );
666 free( p_sys->p_video_cfg );
668 p_sys->p_video_cfg = p_next;
670 free( p_sys->psz_venc );
672 while( p_sys->p_deinterlace_cfg != NULL )
674 config_chain_t *p_next = p_sys->p_deinterlace_cfg->p_next;
676 free( p_sys->p_deinterlace_cfg->psz_name );
677 free( p_sys->p_deinterlace_cfg->psz_value );
678 free( p_sys->p_deinterlace_cfg );
680 p_sys->p_deinterlace_cfg = p_next;
682 free( p_sys->psz_deinterlace );
684 while( p_sys->p_spu_cfg != NULL )
686 config_chain_t *p_next = p_sys->p_spu_cfg->p_next;
688 free( p_sys->p_spu_cfg->psz_name );
689 free( p_sys->p_spu_cfg->psz_value );
690 free( p_sys->p_spu_cfg );
692 p_sys->p_spu_cfg = p_next;
694 free( p_sys->psz_senc );
696 if( p_sys->p_spu ) spu_Destroy( p_sys->p_spu );
698 while( p_sys->p_osd_cfg != NULL )
700 config_chain_t *p_next = p_sys->p_osd_cfg->p_next;
702 free( p_sys->p_osd_cfg->psz_name );
703 free( p_sys->p_osd_cfg->psz_value );
704 free( p_sys->p_osd_cfg );
706 p_sys->p_osd_cfg = p_next;
708 free( p_sys->psz_osdenc );
710 vlc_object_release( p_sys );
713 struct sout_stream_id_t
715 vlc_fourcc_t b_transcode;
717 /* id of the out stream */
721 decoder_t *p_decoder;
724 filter_chain_t *p_f_chain;
725 /* User specified filters */
726 filter_chain_t *p_uf_chain;
729 encoder_t *p_encoder;
732 date_t interpolated_pts;
735 static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
737 sout_stream_sys_t *p_sys = p_stream->p_sys;
738 sout_stream_id_t *id;
740 id = malloc( sizeof( sout_stream_id_t ) );
743 memset( id, 0, sizeof(sout_stream_id_t) );
746 id->p_decoder = NULL;
747 id->p_encoder = NULL;
749 /* Create decoder object */
750 id->p_decoder = vlc_object_create( p_stream, VLC_OBJECT_DECODER );
753 vlc_object_attach( id->p_decoder, p_stream );
754 id->p_decoder->p_module = NULL;
755 id->p_decoder->fmt_in = *p_fmt;
756 id->p_decoder->b_pace_control = true;
758 /* Create encoder object */
759 id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
762 vlc_object_attach( id->p_encoder, p_stream );
763 id->p_encoder->p_module = NULL;
765 /* Create destination format */
766 es_format_Init( &id->p_encoder->fmt_out, p_fmt->i_cat, 0 );
767 id->p_encoder->fmt_out.i_id = p_fmt->i_id;
768 id->p_encoder->fmt_out.i_group = p_fmt->i_group;
769 if( p_fmt->psz_language )
770 id->p_encoder->fmt_out.psz_language = strdup( p_fmt->psz_language );
772 if( p_fmt->i_cat == AUDIO_ES && (p_sys->i_acodec || p_sys->psz_aenc) )
775 "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
776 (char*)&p_fmt->i_codec, (char*)&p_sys->i_acodec );
778 /* Complete destination format */
779 id->p_encoder->fmt_out.i_codec = p_sys->i_acodec;
780 id->p_encoder->fmt_out.audio.i_rate = p_sys->i_sample_rate > 0 ?
781 p_sys->i_sample_rate : p_fmt->audio.i_rate;
782 id->p_encoder->fmt_out.i_bitrate = p_sys->i_abitrate;
783 id->p_encoder->fmt_out.audio.i_bitspersample =
784 p_fmt->audio.i_bitspersample;
785 id->p_encoder->fmt_out.audio.i_channels = p_sys->i_channels > 0 ?
786 p_sys->i_channels : p_fmt->audio.i_channels;
787 /* Sanity check for audio channels */
788 id->p_encoder->fmt_out.audio.i_channels =
789 __MIN( id->p_encoder->fmt_out.audio.i_channels,
790 id->p_decoder->fmt_in.audio.i_channels );
791 id->p_encoder->fmt_out.audio.i_original_channels =
792 id->p_decoder->fmt_in.audio.i_physical_channels;
793 if( id->p_decoder->fmt_in.audio.i_channels ==
794 id->p_encoder->fmt_out.audio.i_channels )
796 id->p_encoder->fmt_out.audio.i_physical_channels =
797 id->p_decoder->fmt_in.audio.i_physical_channels;
801 id->p_encoder->fmt_out.audio.i_physical_channels =
802 pi_channels_maps[id->p_encoder->fmt_out.audio.i_channels];
805 /* Build decoder -> filter -> encoder chain */
806 if( transcode_audio_new( p_stream, id ) )
808 msg_Err( p_stream, "cannot create audio chain" );
812 /* Open output stream */
813 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_encoder->fmt_out );
814 id->b_transcode = true;
818 transcode_audio_close( id );
822 date_Init( &id->interpolated_pts, p_fmt->audio.i_rate, 1 );
824 else if( p_fmt->i_cat == VIDEO_ES &&
825 (p_sys->i_vcodec != 0 || p_sys->psz_venc) )
828 "creating video transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
829 (char*)&p_fmt->i_codec, (char*)&p_sys->i_vcodec );
831 /* Complete destination format */
832 id->p_encoder->fmt_out.i_codec = p_sys->i_vcodec;
833 id->p_encoder->fmt_out.video.i_width = p_sys->i_width & ~1;
834 id->p_encoder->fmt_out.video.i_height = p_sys->i_height & ~1;
835 id->p_encoder->fmt_out.i_bitrate = p_sys->i_vbitrate;
837 /* Build decoder -> filter -> encoder chain */
838 if( transcode_video_new( p_stream, id ) )
840 msg_Err( p_stream, "cannot create video chain" );
844 /* Stream will be added later on because we don't know
845 * all the characteristics of the decoded stream yet */
846 id->b_transcode = true;
848 if( p_sys->f_fps > 0 )
850 id->p_encoder->fmt_out.video.i_frame_rate =
851 (p_sys->f_fps * 1000) + 0.5;
852 id->p_encoder->fmt_out.video.i_frame_rate_base =
856 else if( ( p_fmt->i_cat == SPU_ES ) &&
857 ( p_sys->i_scodec || p_sys->psz_senc ) )
859 msg_Dbg( p_stream, "creating subtitles transcoding from fcc=`%4.4s' "
860 "to fcc=`%4.4s'", (char*)&p_fmt->i_codec,
861 (char*)&p_sys->i_scodec );
863 /* Complete destination format */
864 id->p_encoder->fmt_out.i_codec = p_sys->i_scodec;
866 /* build decoder -> filter -> encoder */
867 if( transcode_spu_new( p_stream, id ) )
869 msg_Err( p_stream, "cannot create subtitles chain" );
873 /* open output stream */
874 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_encoder->fmt_out );
875 id->b_transcode = true;
879 transcode_spu_close( id );
883 else if( p_fmt->i_cat == SPU_ES && p_sys->b_soverlay )
885 msg_Dbg( p_stream, "subtitles (fcc=`%4.4s') overlaying",
886 (char*)&p_fmt->i_codec );
888 id->b_transcode = true;
890 /* Build decoder -> filter -> overlaying chain */
891 if( transcode_spu_new( p_stream, id ) )
893 msg_Err( p_stream, "cannot create subtitles chain" );
897 else if( !p_sys->b_osd && (p_sys->i_osdcodec != 0 || p_sys->psz_osdenc) )
899 msg_Dbg( p_stream, "creating osd transcoding from fcc=`%4.4s' "
900 "to fcc=`%4.4s'", (char*)&p_fmt->i_codec,
901 (char*)&p_sys->i_scodec );
903 id->b_transcode = true;
905 /* Create a fake OSD menu elementary stream */
906 if( transcode_osd_new( p_stream, id ) )
908 msg_Err( p_stream, "cannot create osd chain" );
915 msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
916 (char*)&p_fmt->i_codec );
917 id->id = p_sys->p_out->pf_add( p_sys->p_out, p_fmt );
918 id->b_transcode = false;
920 if( !id->id ) goto error;
930 vlc_object_detach( id->p_decoder );
931 vlc_object_release( id->p_decoder );
932 id->p_decoder = NULL;
937 vlc_object_detach( id->p_encoder );
938 es_format_Clean( &id->p_encoder->fmt_out );
939 vlc_object_release( id->p_encoder );
940 id->p_encoder = NULL;
948 static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
950 sout_stream_sys_t *p_sys = p_stream->p_sys;
952 if( id->b_transcode )
954 switch( id->p_decoder->fmt_in.i_cat )
957 transcode_audio_close( id );
960 transcode_video_close( p_stream, id );
964 transcode_osd_close( p_stream, id );
966 transcode_spu_close( id );
971 if( id->id ) p_sys->p_out->pf_del( p_sys->p_out, id->id );
975 vlc_object_detach( id->p_decoder );
976 vlc_object_release( id->p_decoder );
977 id->p_decoder = NULL;
982 vlc_object_detach( id->p_encoder );
983 es_format_Clean( &id->p_encoder->fmt_out );
984 vlc_object_release( id->p_encoder );
985 id->p_encoder = NULL;
992 static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
995 sout_stream_sys_t *p_sys = p_stream->p_sys;
996 block_t *p_out = NULL;
998 if( !id->b_transcode && id->id )
1000 return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer );
1002 else if( !id->b_transcode )
1004 block_Release( p_buffer );
1005 return VLC_EGENERIC;
1008 switch( id->p_decoder->fmt_in.i_cat )
1011 transcode_audio_process( p_stream, id, p_buffer, &p_out );
1015 if( transcode_video_process( p_stream, id, p_buffer, &p_out )
1018 return VLC_EGENERIC;
1023 /* Transcode OSD menu pictures. */
1026 if( transcode_osd_process( p_stream, id, p_buffer, &p_out ) !=
1029 return VLC_EGENERIC;
1032 else if ( transcode_spu_process( p_stream, id, p_buffer, &p_out ) !=
1035 return VLC_EGENERIC;
1041 block_Release( p_buffer );
1045 if( p_out ) return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_out );
1049 /****************************************************************************
1051 ****************************************************************************/
1052 static inline void video_timer_start( encoder_t * p_encoder )
1054 stats_TimerStart( p_encoder, "encoding video frame",
1055 STATS_TIMER_VIDEO_FRAME_ENCODING );
1058 static inline void video_timer_stop( encoder_t * p_encoder )
1060 stats_TimerStop( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1063 static inline void video_timer_close( encoder_t * p_encoder )
1065 stats_TimerDump( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1066 stats_TimerClean( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1069 static inline void audio_timer_start( encoder_t * p_encoder )
1071 stats_TimerStart( p_encoder, "encoding audio frame",
1072 STATS_TIMER_AUDIO_FRAME_ENCODING );
1075 static inline void audio_timer_stop( encoder_t * p_encoder )
1077 stats_TimerStop( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1080 static inline void audio_timer_close( encoder_t * p_encoder )
1082 stats_TimerDump( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1083 stats_TimerClean( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1086 /****************************************************************************
1087 * decoder reencoder part
1088 ****************************************************************************/
1090 static block_t *transcode_audio_alloc( filter_t *p_filter, int size )
1092 VLC_UNUSED( p_filter );
1093 return block_Alloc( size );
1096 static int transcode_audio_filter_allocation_init( filter_t *p_filter,
1100 p_filter->pf_audio_buffer_new = transcode_audio_alloc;
1104 static int transcode_audio_new( sout_stream_t *p_stream,
1105 sout_stream_id_t *id )
1107 sout_stream_sys_t *p_sys = p_stream->p_sys;
1108 es_format_t fmt_last;
1115 /* Initialization of decoder structures */
1116 id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1117 id->p_decoder->fmt_out.i_extra = 0;
1118 id->p_decoder->fmt_out.p_extra = 0;
1119 id->p_decoder->pf_decode_audio = NULL;
1120 id->p_decoder->pf_aout_buffer_new = audio_new_buffer;
1121 id->p_decoder->pf_aout_buffer_del = audio_del_buffer;
1122 /* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */
1124 id->p_decoder->p_module =
1125 module_Need( id->p_decoder, "decoder", "$codec", 0 );
1126 if( !id->p_decoder->p_module )
1128 msg_Err( p_stream, "cannot find audio decoder" );
1129 return VLC_EGENERIC;
1131 id->p_decoder->fmt_out.audio.i_bitspersample =
1132 aout_BitsPerSample( id->p_decoder->fmt_out.i_codec );
1133 fmt_last = id->p_decoder->fmt_out;
1134 /* Fix AAC SBR changing number of channels and sampling rate */
1135 if( !(id->p_decoder->fmt_in.i_codec == VLC_FOURCC('m','p','4','a') &&
1136 fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate &&
1137 fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels) )
1138 fmt_last.audio.i_rate = id->p_decoder->fmt_in.audio.i_rate;
1144 /* Initialization of encoder format structures */
1145 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1146 id->p_decoder->fmt_out.i_codec );
1147 id->p_encoder->fmt_in.audio.i_format = id->p_decoder->fmt_out.i_codec;
1149 id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;//id->p_encoder->fmt_out.audio.i_rate;
1150 id->p_encoder->fmt_in.audio.i_physical_channels =
1151 id->p_encoder->fmt_out.audio.i_physical_channels;
1152 id->p_encoder->fmt_in.audio.i_original_channels =
1153 id->p_encoder->fmt_out.audio.i_original_channels;
1154 id->p_encoder->fmt_in.audio.i_channels =
1155 id->p_encoder->fmt_out.audio.i_channels;
1156 id->p_encoder->fmt_in.audio.i_bitspersample =
1157 aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1159 id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1160 id->p_encoder->p_module =
1161 module_Need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1162 if( !id->p_encoder->p_module )
1164 msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)",
1165 p_sys->psz_aenc ? p_sys->psz_aenc : "any",
1166 (char *)&p_sys->i_acodec );
1167 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1168 id->p_decoder->p_module = NULL;
1169 return VLC_EGENERIC;
1171 id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1172 id->p_encoder->fmt_in.audio.i_bitspersample =
1173 aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1175 /* Init filter chain */
1176 id->p_f_chain = filter_chain_New( p_stream, "audio filter2", true,
1177 transcode_audio_filter_allocation_init, NULL, NULL );
1178 filter_chain_Reset( id->p_f_chain, &fmt_last, &id->p_encoder->fmt_in );
1180 /* Load conversion filters */
1181 if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels ||
1182 fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1184 /* We'll have to go through fl32 first */
1185 fmt_last.i_codec = fmt_last.audio.i_format = VLC_FOURCC('f','l','3','2');
1186 fmt_last.audio.i_bitspersample = aout_BitsPerSample( fmt_last.i_codec );
1187 filter_chain_AppendFilter( id->p_f_chain, NULL, NULL, NULL, &fmt_last );
1188 fmt_last = *filter_chain_GetFmtOut( id->p_f_chain );
1191 for( i = 0; i < 4; i++ )
1193 if( (fmt_last.audio.i_channels !=
1194 id->p_encoder->fmt_in.audio.i_channels) ||
1195 (fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate) ||
1196 (fmt_last.i_codec != id->p_encoder->fmt_in.i_codec) )
1198 filter_chain_AppendFilter( id->p_f_chain, NULL, NULL, &fmt_last, &id->p_encoder->fmt_in );
1199 fmt_last = *filter_chain_GetFmtOut( id->p_f_chain );
1203 /* Final checks to see if conversions were successful */
1204 if( fmt_last.i_codec != id->p_encoder->fmt_in.i_codec )
1206 msg_Err( p_stream, "no audio filter found (%4.4s->%4.4s)",
1207 (char *)&fmt_last.i_codec,
1208 (char *)&id->p_encoder->fmt_in.i_codec );
1209 transcode_audio_close( id );
1210 return VLC_EGENERIC;
1213 /* Load user specified audio filters now */
1214 if( p_sys->psz_af2 )
1216 id->p_uf_chain = filter_chain_New( p_stream, "audio filter2", false,
1217 transcode_audio_filter_allocation_init, NULL, NULL );
1218 filter_chain_Reset( id->p_uf_chain, &fmt_last, &id->p_encoder->fmt_in );
1219 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_af2 );
1222 if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels )
1225 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1226 id->p_encoder->p_module = NULL;
1228 /* This might work, but only if the encoder is restarted */
1229 id->p_encoder->fmt_in.audio.i_channels = fmt_last.audio.i_channels;
1230 id->p_encoder->fmt_out.audio.i_channels = fmt_last.audio.i_channels;
1232 id->p_encoder->fmt_in.audio.i_physical_channels =
1233 id->p_encoder->fmt_in.audio.i_original_channels =
1234 fmt_last.audio.i_physical_channels;
1235 id->p_encoder->fmt_out.audio.i_physical_channels =
1236 id->p_encoder->fmt_out.audio.i_original_channels =
1237 fmt_last.audio.i_physical_channels;
1239 msg_Dbg( p_stream, "number of audio channels for mixing changed, "
1240 "trying to reopen the encoder for mixing %i to %i channels",
1241 fmt_last.audio.i_channels,
1242 id->p_encoder->fmt_in.audio.i_channels );
1244 /* reload encoder */
1245 id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1246 id->p_encoder->p_module =
1247 module_Need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1248 if( !id->p_encoder->p_module )
1250 msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)",
1251 p_sys->psz_aenc ? p_sys->psz_aenc : "any",
1252 (char *)&p_sys->i_acodec );
1253 transcode_audio_close( id );
1254 return VLC_EGENERIC;
1256 id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1257 id->p_encoder->fmt_in.audio.i_bitspersample =
1258 aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1260 msg_Err( p_stream, "no audio filter found for mixing from"
1261 " %i to %i channels", fmt_last.audio.i_channels,
1262 id->p_encoder->fmt_in.audio.i_channels );
1264 transcode_audio_close( id );
1265 return VLC_EGENERIC;
1269 if( fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1271 msg_Err( p_stream, "no audio filter found for resampling from"
1272 " %iHz to %iHz", fmt_last.audio.i_rate,
1273 id->p_encoder->fmt_in.audio.i_rate );
1275 /* FIXME : this might work, but only if the encoder is restarted */
1276 id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;
1277 id->p_encoder->fmt_out.audio.i_rate = fmt_last.audio.i_rate;
1279 transcode_audio_close( id );
1280 return VLC_EGENERIC;
1284 /* FIXME: Hack for mp3 transcoding support */
1285 if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC( 'm','p','3',' ' ) )
1286 id->p_encoder->fmt_out.i_codec = VLC_FOURCC( 'm','p','g','a' );
1291 static void transcode_audio_close( sout_stream_id_t *id )
1293 audio_timer_close( id->p_encoder );
1296 if( id->p_decoder->p_module )
1297 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1298 id->p_decoder->p_module = NULL;
1301 if( id->p_encoder->p_module )
1302 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1303 id->p_encoder->p_module = NULL;
1307 filter_chain_Delete( id->p_f_chain );
1308 if( id->p_uf_chain )
1309 filter_chain_Delete( id->p_uf_chain );
1312 static int transcode_audio_process( sout_stream_t *p_stream,
1313 sout_stream_id_t *id,
1314 block_t *in, block_t **out )
1316 sout_stream_sys_t *p_sys = p_stream->p_sys;
1317 aout_buffer_t *p_audio_buf;
1318 block_t *p_block, *p_audio_block;
1321 while( (p_audio_buf = id->p_decoder->pf_decode_audio( id->p_decoder,
1324 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_AUDIO, 1 );
1325 if( p_sys->b_master_sync )
1327 mtime_t i_dts = date_Get( &id->interpolated_pts ) + 1;
1328 if ( p_audio_buf->start_date - i_dts > MASTER_SYNC_MAX_DRIFT
1329 || p_audio_buf->start_date - i_dts < -MASTER_SYNC_MAX_DRIFT )
1331 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1332 date_Set( &id->interpolated_pts, p_audio_buf->start_date );
1333 i_dts = p_audio_buf->start_date + 1;
1335 p_sys->i_master_drift = p_audio_buf->start_date - i_dts;
1336 date_Increment( &id->interpolated_pts, p_audio_buf->i_nb_samples );
1337 p_audio_buf->start_date -= p_sys->i_master_drift;
1338 p_audio_buf->end_date -= p_sys->i_master_drift;
1341 p_audio_block = p_audio_buf->p_sys;
1342 p_audio_block->i_buffer = p_audio_buf->i_nb_bytes;
1343 p_audio_block->i_dts = p_audio_block->i_pts =
1344 p_audio_buf->start_date;
1345 p_audio_block->i_length = p_audio_buf->end_date -
1346 p_audio_buf->start_date;
1347 p_audio_block->i_samples = p_audio_buf->i_nb_samples;
1349 /* Run filter chain */
1350 p_audio_block = filter_chain_AudioFilter( id->p_f_chain, p_audio_block );
1351 if( id->p_uf_chain )
1352 p_audio_block = filter_chain_AudioFilter( id->p_uf_chain, p_audio_block );
1353 assert( p_audio_block );
1355 p_audio_buf->p_buffer = p_audio_block->p_buffer;
1356 p_audio_buf->i_nb_bytes = p_audio_block->i_buffer;
1357 p_audio_buf->i_nb_samples = p_audio_block->i_samples;
1358 p_audio_buf->start_date = p_audio_block->i_dts;
1359 p_audio_buf->end_date = p_audio_block->i_dts + p_audio_block->i_length;
1361 audio_timer_start( id->p_encoder );
1362 p_block = id->p_encoder->pf_encode_audio( id->p_encoder, p_audio_buf );
1363 audio_timer_stop( id->p_encoder );
1365 block_ChainAppend( out, p_block );
1366 block_Release( p_audio_block );
1367 free( p_audio_buf );
1373 static void audio_release_buffer( aout_buffer_t *p_buffer )
1375 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1379 static aout_buffer_t *audio_new_buffer( decoder_t *p_dec, int i_samples )
1381 aout_buffer_t *p_buffer;
1385 if( p_dec->fmt_out.audio.i_bitspersample )
1387 i_size = i_samples * p_dec->fmt_out.audio.i_bitspersample / 8 *
1388 p_dec->fmt_out.audio.i_channels;
1390 else if( p_dec->fmt_out.audio.i_bytes_per_frame &&
1391 p_dec->fmt_out.audio.i_frame_length )
1393 i_size = i_samples * p_dec->fmt_out.audio.i_bytes_per_frame /
1394 p_dec->fmt_out.audio.i_frame_length;
1398 i_size = i_samples * 4 * p_dec->fmt_out.audio.i_channels;
1401 p_buffer = malloc( sizeof(aout_buffer_t) );
1402 if( !p_buffer ) return NULL;
1403 p_buffer->b_discontinuity = false;
1404 p_buffer->pf_release = audio_release_buffer;
1405 p_buffer->p_sys = p_block = block_New( p_dec, i_size );
1407 p_buffer->p_buffer = p_block->p_buffer;
1408 p_buffer->i_size = p_buffer->i_nb_bytes = p_block->i_buffer;
1409 p_buffer->i_nb_samples = i_samples;
1410 p_block->i_samples = i_samples;
1415 static void audio_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
1418 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1426 static int transcode_video_filter_allocation_init( filter_t *p_filter,
1429 sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_data;
1432 p_filter->pf_vout_buffer_new = video_new_buffer_filter;
1433 p_filter->pf_vout_buffer_del = video_del_buffer_filter;
1435 p_filter->p_owner = malloc( sizeof(filter_owner_sys_t) );
1436 if( !p_filter->p_owner )
1437 return VLC_EGENERIC;
1439 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1440 p_filter->p_owner->pp_pics[i] = 0;
1441 p_filter->p_owner->p_sys = p_sys;
1446 static void transcode_video_filter_allocation_clear( filter_t *p_filter )
1450 /* Clean-up pictures ring buffer */
1451 for( j = 0; j < PICTURE_RING_SIZE; j++ )
1453 if( p_filter->p_owner->pp_pics[j] )
1454 video_del_buffer( VLC_OBJECT(p_filter),
1455 p_filter->p_owner->pp_pics[j] );
1457 free( p_filter->p_owner );
1460 static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
1462 sout_stream_sys_t *p_sys = p_stream->p_sys;
1466 * Initialization of decoder structures
1468 id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1469 id->p_decoder->fmt_out.i_extra = 0;
1470 id->p_decoder->fmt_out.p_extra = 0;
1471 id->p_decoder->pf_decode_video = NULL;
1472 id->p_decoder->pf_get_cc = NULL;
1473 id->p_decoder->pf_get_cc = 0;
1474 id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
1475 id->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder;
1476 id->p_decoder->pf_picture_link = video_link_picture_decoder;
1477 id->p_decoder->pf_picture_unlink = video_unlink_picture_decoder;
1478 id->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) );
1479 if( !id->p_decoder->p_owner )
1480 return VLC_EGENERIC;
1482 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1483 id->p_decoder->p_owner->pp_pics[i] = 0;
1484 id->p_decoder->p_owner->p_sys = p_sys;
1485 /* id->p_decoder->p_cfg = p_sys->p_video_cfg; */
1487 id->p_decoder->p_module =
1488 module_Need( id->p_decoder, "decoder", "$codec", 0 );
1490 if( !id->p_decoder->p_module )
1492 msg_Err( p_stream, "cannot find video decoder" );
1493 free( id->p_decoder->p_owner );
1494 return VLC_EGENERIC;
1499 * Because some info about the decoded input will only be available
1500 * once the first frame is decoded, we actually only test the availability
1501 * of the encoder here.
1504 /* Initialization of encoder format structures */
1505 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1506 id->p_decoder->fmt_out.i_codec );
1507 id->p_encoder->fmt_in.video.i_chroma = id->p_decoder->fmt_out.i_codec;
1509 /* The dimensions will be set properly later on.
1510 * Just put sensible values so we can test an encoder is available. */
1511 id->p_encoder->fmt_in.video.i_width =
1512 id->p_encoder->fmt_out.video.i_width ?:
1513 id->p_decoder->fmt_in.video.i_width ?: 16;
1514 id->p_encoder->fmt_in.video.i_height =
1515 id->p_encoder->fmt_out.video.i_height ?:
1516 id->p_decoder->fmt_in.video.i_height ?: 16;
1517 id->p_encoder->fmt_in.video.i_frame_rate = ENC_FRAMERATE;
1518 id->p_encoder->fmt_in.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1520 id->p_encoder->i_threads = p_sys->i_threads;
1521 id->p_encoder->p_cfg = p_sys->p_video_cfg;
1523 id->p_encoder->p_module =
1524 module_Need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1525 if( !id->p_encoder->p_module )
1527 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1528 p_sys->psz_venc ? p_sys->psz_venc : "any",
1529 (char *)&p_sys->i_vcodec );
1530 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1531 id->p_decoder->p_module = 0;
1532 free( id->p_decoder->p_owner );
1533 return VLC_EGENERIC;
1536 /* Close the encoder.
1537 * We'll open it only when we have the first frame. */
1538 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1539 if( id->p_encoder->fmt_out.p_extra )
1541 free( id->p_encoder->fmt_out.p_extra );
1542 id->p_encoder->fmt_out.p_extra = NULL;
1543 id->p_encoder->fmt_out.i_extra = 0;
1545 id->p_encoder->p_module = NULL;
1547 if( p_sys->i_threads >= 1 )
1549 int i_priority = p_sys->b_high_priority ? VLC_THREAD_PRIORITY_OUTPUT :
1550 VLC_THREAD_PRIORITY_VIDEO;
1551 p_sys->id_video = id;
1552 vlc_mutex_init( &p_sys->lock_out );
1553 vlc_cond_init( p_stream, &p_sys->cond );
1554 memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) );
1555 p_sys->i_first_pic = 0;
1556 p_sys->i_last_pic = 0;
1557 p_sys->p_buffers = NULL;
1558 p_sys->b_die = p_sys->b_error = 0;
1559 if( vlc_thread_create( p_sys, "encoder", EncoderThread, i_priority,
1562 msg_Err( p_stream, "cannot spawn encoder thread" );
1563 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1564 id->p_decoder->p_module = 0;
1565 free( id->p_decoder->p_owner );
1566 return VLC_EGENERIC;
1573 static void transcode_video_encoder_init( sout_stream_t *p_stream,
1574 sout_stream_id_t *id )
1576 sout_stream_sys_t *p_sys = p_stream->p_sys;
1578 /* Calculate scaling
1579 * width/height of source */
1580 int i_src_width = id->p_decoder->fmt_out.video.i_width;
1581 int i_src_height = id->p_decoder->fmt_out.video.i_height;
1583 /* with/height scaling */
1584 float f_scale_width = 1;
1585 float f_scale_height = 1;
1587 /* width/height of output stream */
1592 float f_aspect = (float)id->p_decoder->fmt_out.video.i_aspect /
1595 msg_Dbg( p_stream, "decoder aspect is %i:%i",
1596 id->p_decoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1598 /* Change f_aspect from source frame to source pixel */
1599 f_aspect = f_aspect * i_src_height / i_src_width;
1600 msg_Dbg( p_stream, "source pixel aspect is %f:1", f_aspect );
1602 /* Calculate scaling factor for specified parameters */
1603 if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1604 id->p_encoder->fmt_out.video.i_height <= 0 && p_sys->f_scale )
1606 /* Global scaling. Make sure width will remain a factor of 16 */
1609 int i_new_width = i_src_width * p_sys->f_scale;
1611 if( i_new_width % 16 <= 7 && i_new_width >= 16 )
1612 i_new_width -= i_new_width % 16;
1614 i_new_width += 16 - i_new_width % 16;
1616 f_real_scale = (float)( i_new_width ) / (float) i_src_width;
1618 i_new_height = __MAX( 16, i_src_height * (float)f_real_scale );
1620 f_scale_width = f_real_scale;
1621 f_scale_height = (float) i_new_height / (float) i_src_height;
1623 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1624 id->p_encoder->fmt_out.video.i_height <= 0 )
1626 /* Only width specified */
1627 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1628 f_scale_height = f_scale_width;
1630 else if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1631 id->p_encoder->fmt_out.video.i_height > 0 )
1633 /* Only height specified */
1634 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1635 f_scale_width = f_scale_height;
1637 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1638 id->p_encoder->fmt_out.video.i_height > 0 )
1640 /* Width and height specified */
1641 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1642 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1645 /* check maxwidth and maxheight
1647 if( p_sys->i_maxwidth && f_scale_width > (float)p_sys->i_maxwidth /
1650 f_scale_width = (float)p_sys->i_maxwidth / i_src_width;
1653 if( p_sys->i_maxheight && f_scale_height > (float)p_sys->i_maxheight /
1656 f_scale_height = (float)p_sys->i_maxheight / i_src_height;
1660 /* Change aspect ratio from source pixel to scaled pixel */
1661 f_aspect = f_aspect * f_scale_height / f_scale_width;
1662 msg_Dbg( p_stream, "scaled pixel aspect is %f:1", f_aspect );
1664 /* f_scale_width and f_scale_height are now final */
1665 /* Calculate width, height from scaling
1666 * Make sure its multiple of 2
1668 i_dst_width = 2 * (int)(f_scale_width*i_src_width/2+0.5);
1669 i_dst_height = 2 * (int)(f_scale_height*i_src_height/2+0.5);
1671 /* Change aspect ratio from scaled pixel to output frame */
1672 f_aspect = f_aspect * i_dst_width / i_dst_height;
1674 /* Store calculated values */
1675 id->p_encoder->fmt_out.video.i_width =
1676 id->p_encoder->fmt_out.video.i_visible_width = i_dst_width;
1677 id->p_encoder->fmt_out.video.i_height =
1678 id->p_encoder->fmt_out.video.i_visible_height = i_dst_height;
1680 id->p_encoder->fmt_in.video.i_width =
1681 id->p_encoder->fmt_in.video.i_visible_width = i_dst_width;
1682 id->p_encoder->fmt_in.video.i_height =
1683 id->p_encoder->fmt_in.video.i_visible_height = i_dst_height;
1685 msg_Dbg( p_stream, "source %ix%i, destination %ix%i",
1686 i_src_width, i_src_height,
1687 i_dst_width, i_dst_height
1690 /* Handle frame rate conversion */
1691 if( !id->p_encoder->fmt_out.video.i_frame_rate ||
1692 !id->p_encoder->fmt_out.video.i_frame_rate_base )
1694 if( id->p_decoder->fmt_out.video.i_frame_rate &&
1695 id->p_decoder->fmt_out.video.i_frame_rate_base )
1697 id->p_encoder->fmt_out.video.i_frame_rate =
1698 id->p_decoder->fmt_out.video.i_frame_rate;
1699 id->p_encoder->fmt_out.video.i_frame_rate_base =
1700 id->p_decoder->fmt_out.video.i_frame_rate_base;
1704 /* Pick a sensible default value */
1705 id->p_encoder->fmt_out.video.i_frame_rate = ENC_FRAMERATE;
1706 id->p_encoder->fmt_out.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1710 id->p_encoder->fmt_in.video.i_frame_rate =
1711 id->p_encoder->fmt_out.video.i_frame_rate;
1712 id->p_encoder->fmt_in.video.i_frame_rate_base =
1713 id->p_encoder->fmt_out.video.i_frame_rate_base;
1715 date_Init( &id->interpolated_pts,
1716 id->p_encoder->fmt_out.video.i_frame_rate,
1717 id->p_encoder->fmt_out.video.i_frame_rate_base );
1719 /* Check whether a particular aspect ratio was requested */
1720 if( !id->p_encoder->fmt_out.video.i_aspect )
1722 id->p_encoder->fmt_out.video.i_aspect =
1723 (int)( f_aspect * VOUT_ASPECT_FACTOR + 0.5 );
1725 id->p_encoder->fmt_in.video.i_aspect =
1726 id->p_encoder->fmt_out.video.i_aspect;
1728 msg_Dbg( p_stream, "encoder aspect is %i:%i",
1729 id->p_encoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1731 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1734 static int transcode_video_encoder_open( sout_stream_t *p_stream,
1735 sout_stream_id_t *id )
1737 sout_stream_sys_t *p_sys = p_stream->p_sys;
1740 msg_Dbg( p_stream, "destination (after video filters) %ix%i",
1741 id->p_encoder->fmt_in.video.i_width,
1742 id->p_encoder->fmt_in.video.i_height );
1744 id->p_encoder->p_module =
1745 module_Need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1746 if( !id->p_encoder->p_module )
1748 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1749 p_sys->psz_venc ? p_sys->psz_venc : "any",
1750 (char *)&p_sys->i_vcodec );
1751 return VLC_EGENERIC;
1754 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1756 /* Hack for mp2v/mp1v transcoding support */
1757 if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','1','v') ||
1758 id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','2','v') )
1760 id->p_encoder->fmt_out.i_codec = VLC_FOURCC('m','p','g','v');
1763 id->id = p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out,
1764 &id->p_encoder->fmt_out );
1767 msg_Err( p_stream, "cannot add this stream" );
1768 return VLC_EGENERIC;
1774 static void transcode_video_close( sout_stream_t *p_stream,
1775 sout_stream_id_t *id )
1779 if( p_stream->p_sys->i_threads >= 1 )
1781 vlc_mutex_lock( &p_stream->p_sys->lock_out );
1782 vlc_object_kill( p_stream->p_sys );
1783 vlc_cond_signal( &p_stream->p_sys->cond );
1784 vlc_mutex_unlock( &p_stream->p_sys->lock_out );
1785 vlc_thread_join( p_stream->p_sys );
1786 vlc_mutex_destroy( &p_stream->p_sys->lock_out );
1787 vlc_cond_destroy( &p_stream->p_sys->cond );
1790 video_timer_close( id->p_encoder );
1793 if( id->p_decoder->p_module )
1794 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1796 if( id->p_decoder->p_owner )
1798 /* Clean-up pictures ring buffer */
1799 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1801 if( id->p_decoder->p_owner->pp_pics[i] )
1802 video_del_buffer( VLC_OBJECT(id->p_decoder),
1803 id->p_decoder->p_owner->pp_pics[i] );
1805 free( id->p_decoder->p_owner );
1809 if( id->p_encoder->p_module )
1810 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1814 filter_chain_Delete( id->p_f_chain );
1815 if( id->p_uf_chain )
1816 filter_chain_Delete( id->p_uf_chain );
1819 static int transcode_video_process( sout_stream_t *p_stream,
1820 sout_stream_id_t *id,
1821 block_t *in, block_t **out )
1823 sout_stream_sys_t *p_sys = p_stream->p_sys;
1824 int i_duplicate = 1;
1825 picture_t *p_pic, *p_pic2 = NULL;
1828 while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
1830 subpicture_t *p_subpic = NULL;
1832 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_VIDEO, 1 );
1834 if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )
1836 mtime_t current_date = mdate();
1837 if( current_date + 50000 > p_pic->date )
1839 msg_Dbg( p_stream, "late picture skipped (%"PRId64")",
1840 current_date + 50000 - p_pic->date );
1841 p_pic->pf_release( p_pic );
1846 if( p_sys->b_master_sync )
1848 mtime_t i_video_drift;
1849 mtime_t i_master_drift = p_sys->i_master_drift;
1852 i_pts = date_Get( &id->interpolated_pts ) + 1;
1853 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1854 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
1856 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1857 date_Set( &id->interpolated_pts, p_pic->date );
1858 i_pts = p_pic->date + 1;
1860 i_video_drift = p_pic->date - i_pts;
1863 /* Set the pts of the frame being encoded */
1864 p_pic->date = i_pts;
1866 if( i_video_drift < (i_master_drift - 50000) )
1869 msg_Dbg( p_stream, "dropping frame (%i)",
1870 (int)(i_video_drift - i_master_drift) );
1872 p_pic->pf_release( p_pic );
1875 else if( i_video_drift > (i_master_drift + 50000) )
1878 msg_Dbg( p_stream, "adding frame (%i)",
1879 (int)(i_video_drift - i_master_drift) );
1885 if( !id->p_encoder->p_module )
1887 transcode_video_encoder_init( p_stream, id );
1889 id->p_f_chain = filter_chain_New( p_stream, "video filter2",
1891 transcode_video_filter_allocation_init,
1892 transcode_video_filter_allocation_clear,
1896 if( p_stream->p_sys->b_deinterlace )
1898 filter_chain_AppendFilter( id->p_f_chain,
1899 p_sys->psz_deinterlace,
1900 p_sys->p_deinterlace_cfg,
1901 &id->p_decoder->fmt_out,
1902 &id->p_decoder->fmt_out );
1905 /* Take care of the scaling and chroma conversions */
1906 if( ( id->p_decoder->fmt_out.video.i_chroma !=
1907 id->p_encoder->fmt_in.video.i_chroma ) ||
1908 ( id->p_decoder->fmt_out.video.i_width !=
1909 id->p_encoder->fmt_in.video.i_width ) ||
1910 ( id->p_decoder->fmt_out.video.i_height !=
1911 id->p_encoder->fmt_in.video.i_height ) )
1913 filter_chain_AppendFilter( id->p_f_chain,
1915 &id->p_decoder->fmt_out,
1916 &id->p_encoder->fmt_in );
1919 if( p_sys->psz_vf2 )
1921 const es_format_t *p_fmt_out;
1922 id->p_uf_chain = filter_chain_New( p_stream, "video filter2",
1924 transcode_video_filter_allocation_init,
1925 transcode_video_filter_allocation_clear,
1927 filter_chain_Reset( id->p_uf_chain, &id->p_encoder->fmt_in,
1928 &id->p_encoder->fmt_in );
1929 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_vf2 );
1930 p_fmt_out = filter_chain_GetFmtOut( id->p_uf_chain );
1931 es_format_Copy( &id->p_encoder->fmt_in, p_fmt_out );
1932 id->p_encoder->fmt_out.video.i_width =
1933 id->p_encoder->fmt_in.video.i_width;
1934 id->p_encoder->fmt_out.video.i_height =
1935 id->p_encoder->fmt_in.video.i_height;
1938 if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS )
1940 filter_chain_Delete( id->p_f_chain );
1941 if( id->p_uf_chain )
1942 filter_chain_Delete( id->p_uf_chain );
1943 p_pic->pf_release( p_pic );
1944 transcode_video_close( p_stream, id );
1945 id->b_transcode = false;
1946 return VLC_EGENERIC;
1950 /* Run filter chain */
1952 p_pic = filter_chain_VideoFilter( id->p_f_chain, p_pic );
1958 /* Check if we have a subpicture to overlay */
1961 p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date,
1962 false /* Fixme: check if stream is paused */ );
1963 /* TODO: get another pic */
1966 /* Overlay subpicture */
1969 int i_scale_width, i_scale_height;
1972 i_scale_width = id->p_encoder->fmt_in.video.i_width * 1000 /
1973 id->p_decoder->fmt_out.video.i_width;
1974 i_scale_height = id->p_encoder->fmt_in.video.i_height * 1000 /
1975 id->p_decoder->fmt_out.video.i_height;
1977 if( p_pic->i_refcount && !filter_chain_GetLength( id->p_f_chain ) )
1979 /* We can't modify the picture, we need to duplicate it */
1980 picture_t *p_tmp = video_new_buffer_decoder( id->p_decoder );
1983 vout_CopyPicture( p_stream, p_tmp, p_pic );
1984 p_pic->pf_release( p_pic );
1989 if( filter_chain_GetLength( id->p_f_chain ) > 0 )
1990 fmt = filter_chain_GetFmtOut( id->p_f_chain )->video;
1992 fmt = id->p_decoder->fmt_out.video;
1994 /* FIXME (shouldn't have to be done here) */
1995 fmt.i_sar_num = fmt.i_aspect * fmt.i_height / fmt.i_width;
1996 fmt.i_sar_den = VOUT_ASPECT_FACTOR;
1998 spu_RenderSubpictures( p_sys->p_spu, &fmt, p_pic, p_pic, p_subpic,
1999 i_scale_width, i_scale_height );
2002 /* Run user specified filter chain */
2003 if( id->p_uf_chain )
2004 p_pic = filter_chain_VideoFilter( id->p_uf_chain, p_pic );
2006 if( p_sys->i_threads == 0 )
2010 video_timer_start( id->p_encoder );
2011 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2012 video_timer_stop( id->p_encoder );
2014 block_ChainAppend( out, p_block );
2017 if( p_sys->b_master_sync )
2019 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
2020 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
2021 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
2023 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2024 date_Set( &id->interpolated_pts, p_pic->date );
2025 i_pts = p_pic->date + 1;
2027 date_Increment( &id->interpolated_pts, 1 );
2030 if( p_sys->b_master_sync && i_duplicate > 1 )
2032 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
2033 if( (p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT)
2034 || ((p_pic->date - i_pts) < -MASTER_SYNC_MAX_DRIFT) )
2036 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2037 date_Set( &id->interpolated_pts, p_pic->date );
2038 i_pts = p_pic->date + 1;
2040 date_Increment( &id->interpolated_pts, 1 );
2042 if( p_sys->i_threads >= 1 )
2044 /* We can't modify the picture, we need to duplicate it */
2045 p_pic2 = video_new_buffer_decoder( id->p_decoder );
2046 if( p_pic2 != NULL )
2048 vout_CopyPicture( p_stream, p_pic2, p_pic );
2049 p_pic2->date = i_pts;
2055 p_pic->date = i_pts;
2056 video_timer_start( id->p_encoder );
2057 p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);
2058 video_timer_stop( id->p_encoder );
2059 block_ChainAppend( out, p_block );
2063 if( p_sys->i_threads == 0 )
2065 p_pic->pf_release( p_pic );
2069 vlc_mutex_lock( &p_sys->lock_out );
2070 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
2071 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2072 *out = p_sys->p_buffers;
2073 p_sys->p_buffers = NULL;
2074 if( p_pic2 != NULL )
2076 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic2;
2077 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2079 vlc_cond_signal( &p_sys->cond );
2080 vlc_mutex_unlock( &p_sys->lock_out );
2087 static void* EncoderThread( vlc_object_t* p_this )
2089 sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_this;
2090 sout_stream_id_t *id = p_sys->id_video;
2093 while( vlc_object_alive (p_sys) && !p_sys->b_error )
2097 vlc_mutex_lock( &p_sys->lock_out );
2098 while( p_sys->i_last_pic == p_sys->i_first_pic )
2100 vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );
2101 if( !vlc_object_alive (p_sys) || p_sys->b_error ) break;
2103 if( !vlc_object_alive (p_sys) || p_sys->b_error )
2105 vlc_mutex_unlock( &p_sys->lock_out );
2109 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2110 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2111 vlc_mutex_unlock( &p_sys->lock_out );
2113 video_timer_start( id->p_encoder );
2114 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2115 video_timer_stop( id->p_encoder );
2117 vlc_mutex_lock( &p_sys->lock_out );
2118 block_ChainAppend( &p_sys->p_buffers, p_block );
2120 vlc_mutex_unlock( &p_sys->lock_out );
2121 p_pic->pf_release( p_pic );
2124 while( p_sys->i_last_pic != p_sys->i_first_pic )
2126 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2127 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2128 p_pic->pf_release( p_pic );
2130 block_ChainRelease( p_sys->p_buffers );
2135 struct picture_sys_t
2137 vlc_object_t *p_owner;
2140 static void video_release_buffer( picture_t *p_pic )
2142 if( p_pic && !p_pic->i_refcount && p_pic->pf_release && p_pic->p_sys )
2144 video_del_buffer_decoder( (decoder_t *)p_pic->p_sys->p_owner, p_pic );
2146 else if( p_pic && p_pic->i_refcount > 0 ) p_pic->i_refcount--;
2149 static picture_t *video_new_buffer( vlc_object_t *p_this, picture_t **pp_ring,
2150 sout_stream_sys_t *p_sys )
2152 decoder_t *p_dec = (decoder_t *)p_this;
2156 /* Find an empty space in the picture ring buffer */
2157 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2159 if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2161 pp_ring[i]->i_status = RESERVED_PICTURE;
2165 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2167 if( pp_ring[i] == 0 ) break;
2170 if( i == PICTURE_RING_SIZE && p_sys->i_threads >= 1 )
2172 int i_first_pic = p_sys->i_first_pic;
2174 if( p_sys->i_first_pic != p_sys->i_last_pic )
2176 /* Encoder still has stuff to encode, wait to clear-up the list */
2177 while( p_sys->i_first_pic == i_first_pic )
2181 /* Find an empty space in the picture ring buffer */
2182 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2184 if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2186 pp_ring[i]->i_status = RESERVED_PICTURE;
2190 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2192 if( pp_ring[i] == 0 ) break;
2196 if( i == PICTURE_RING_SIZE )
2198 msg_Err( p_this, "decoder/filter is leaking pictures, "
2199 "resetting its ring buffer" );
2201 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2203 pp_ring[i]->pf_release( pp_ring[i] );
2209 p_pic = malloc( sizeof(picture_t) );
2210 if( !p_pic ) return NULL;
2211 p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
2212 vout_AllocatePicture( VLC_OBJECT(p_dec), p_pic,
2213 p_dec->fmt_out.video.i_chroma,
2214 p_dec->fmt_out.video.i_width,
2215 p_dec->fmt_out.video.i_height,
2216 p_dec->fmt_out.video.i_aspect );
2218 if( !p_pic->i_planes )
2224 p_pic->pf_release = video_release_buffer;
2225 p_pic->p_sys = malloc( sizeof(picture_sys_t) );
2232 p_pic->p_sys->p_owner = p_this;
2233 p_pic->i_status = RESERVED_PICTURE;
2239 static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
2241 return video_new_buffer( VLC_OBJECT(p_dec),
2242 p_dec->p_owner->pp_pics, p_dec->p_owner->p_sys );
2245 static picture_t *video_new_buffer_filter( filter_t *p_filter )
2247 return video_new_buffer( VLC_OBJECT(p_filter),
2248 p_filter->p_owner->pp_pics,
2249 p_filter->p_owner->p_sys );
2252 static void video_del_buffer( vlc_object_t *p_this, picture_t *p_pic )
2257 free( p_pic->p_data_orig );
2258 free( p_pic->p_sys );
2263 static void video_del_buffer_decoder( decoder_t *p_decoder, picture_t *p_pic )
2265 VLC_UNUSED(p_decoder);
2266 p_pic->i_refcount = 0;
2267 p_pic->i_status = DESTROYED_PICTURE;
2270 static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic )
2272 VLC_UNUSED(p_filter);
2273 p_pic->i_refcount = 0;
2274 p_pic->i_status = DESTROYED_PICTURE;
2277 static void video_link_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2280 p_pic->i_refcount++;
2283 static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2286 video_release_buffer( p_pic );
2292 static subpicture_t *spu_new_buffer( decoder_t * );
2293 static void spu_del_buffer( decoder_t *, subpicture_t * );
2295 static int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2297 sout_stream_sys_t *p_sys = p_stream->p_sys;
2303 /* Initialization of decoder structures */
2304 id->p_decoder->pf_decode_sub = NULL;
2305 id->p_decoder->pf_spu_buffer_new = spu_new_buffer;
2306 id->p_decoder->pf_spu_buffer_del = spu_del_buffer;
2307 id->p_decoder->p_owner = (decoder_owner_sys_t *)p_stream;
2308 /* id->p_decoder->p_cfg = p_sys->p_spu_cfg; */
2310 id->p_decoder->p_module =
2311 module_Need( id->p_decoder, "decoder", "$codec", 0 );
2313 if( !id->p_decoder->p_module )
2315 msg_Err( p_stream, "cannot find spu decoder" );
2316 return VLC_EGENERIC;
2319 if( !p_sys->b_soverlay )
2322 /* Initialization of encoder format structures */
2323 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2324 id->p_decoder->fmt_in.i_codec );
2326 id->p_encoder->p_cfg = p_sys->p_spu_cfg;
2328 id->p_encoder->p_module =
2329 module_Need( id->p_encoder, "encoder", p_sys->psz_senc, true );
2331 if( !id->p_encoder->p_module )
2333 module_Unneed( id->p_decoder, id->p_decoder->p_module );
2334 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_senc );
2335 return VLC_EGENERIC;
2341 p_sys->p_spu = spu_Create( p_stream );
2342 spu_Init( p_sys->p_spu );
2348 static void transcode_spu_close( sout_stream_id_t *id)
2351 if( id->p_decoder->p_module )
2352 module_Unneed( id->p_decoder, id->p_decoder->p_module );
2355 if( id->p_encoder->p_module )
2356 module_Unneed( id->p_encoder, id->p_encoder->p_module );
2359 static int transcode_spu_process( sout_stream_t *p_stream,
2360 sout_stream_id_t *id,
2361 block_t *in, block_t **out )
2363 sout_stream_sys_t *p_sys = p_stream->p_sys;
2364 subpicture_t *p_subpic;
2367 p_subpic = id->p_decoder->pf_decode_sub( id->p_decoder, &in );
2369 return VLC_EGENERIC;
2371 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_SUBTITLE, 1 );
2373 if( p_sys->b_master_sync && p_sys->i_master_drift )
2375 p_subpic->i_start -= p_sys->i_master_drift;
2376 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2379 if( p_sys->b_soverlay )
2381 spu_DisplaySubpicture( p_sys->p_spu, p_subpic );
2387 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2388 spu_del_buffer( id->p_decoder, p_subpic );
2391 block_ChainAppend( out, p_block );
2396 return VLC_EGENERIC;
2399 static subpicture_t *spu_new_buffer( decoder_t *p_dec )
2401 sout_stream_t *p_stream = (sout_stream_t *)p_dec->p_owner;
2402 return spu_CreateSubpicture( p_stream->p_sys->p_spu );
2405 static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
2407 sout_stream_t *p_stream = (sout_stream_t *)p_dec->p_owner;
2408 spu_DestroySubpicture( p_stream->p_sys->p_spu, p_subpic );
2414 static int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2416 sout_stream_sys_t *p_sys = p_stream->p_sys;
2418 id->p_decoder->fmt_in.i_cat = SPU_ES;
2419 id->p_encoder->fmt_out.psz_language = strdup( "osd" );
2421 if( p_sys->i_osdcodec != 0 || p_sys->psz_osdenc )
2423 msg_Dbg( p_stream, "creating osdmenu transcoding from fcc=`%4.4s' "
2424 "to fcc=`%4.4s'", (char*)&id->p_encoder->fmt_out.i_codec,
2425 (char*)&p_sys->i_osdcodec );
2427 /* Complete destination format */
2428 id->p_encoder->fmt_out.i_codec = p_sys->i_osdcodec;
2431 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2432 VLC_FOURCC('Y','U','V','A') );
2433 id->p_encoder->fmt_in.psz_language = strdup( "osd" );
2435 id->p_encoder->p_cfg = p_sys->p_osd_cfg;
2437 id->p_encoder->p_module =
2438 module_Need( id->p_encoder, "encoder", p_sys->psz_osdenc, true );
2440 if( !id->p_encoder->p_module )
2442 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_osdenc );
2446 /* open output stream */
2447 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_encoder->fmt_out );
2448 id->b_transcode = true;
2450 if( !id->id ) goto error;
2454 msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
2455 (char*)&id->p_decoder->fmt_out.i_codec );
2456 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_decoder->fmt_out );
2457 id->b_transcode = false;
2459 if( !id->id ) goto error;
2464 p_sys->p_spu = spu_Create( p_stream );
2465 spu_Init( p_sys->p_spu );
2471 msg_Err( p_stream, "starting osd encoding thread failed" );
2472 if( id->p_encoder->p_module )
2473 module_Unneed( id->p_encoder, id->p_encoder->p_module );
2474 p_sys->b_osd = false;
2475 return VLC_EGENERIC;
2478 static void transcode_osd_close( sout_stream_t *p_stream, sout_stream_id_t *id)
2480 sout_stream_sys_t *p_sys = p_stream->p_sys;
2485 if( id->p_encoder->p_module )
2486 module_Unneed( id->p_encoder, id->p_encoder->p_module );
2488 p_sys->b_osd = false;
2491 static int transcode_osd_process( sout_stream_t *p_stream,
2492 sout_stream_id_t *id,
2493 block_t *in, block_t **out )
2495 sout_stream_sys_t *p_sys = p_stream->p_sys;
2496 subpicture_t *p_subpic = NULL;
2498 /* Check if we have a subpicture to send */
2499 if( p_sys->p_spu && in->i_dts > 0)
2501 p_subpic = spu_SortSubpictures( p_sys->p_spu, in->i_dts, false );
2505 msg_Warn( p_stream, "spu channel not initialized, doing it now" );
2508 p_sys->p_spu = spu_Create( p_stream );
2509 spu_Init( p_sys->p_spu );
2515 block_t *p_block = NULL;
2517 if( p_sys->b_master_sync && p_sys->i_master_drift )
2519 p_subpic->i_start -= p_sys->i_master_drift;
2520 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2523 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2524 spu_DestroySubpicture( p_sys->p_spu, p_subpic );
2527 p_block->i_dts = p_block->i_pts = in->i_dts;
2528 block_ChainAppend( out, p_block );
2532 return VLC_EGENERIC;