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 msg_Dbg( p_stream, "Looking for filter "
1199 "(%4.4s->%4.4s, channels %d->%d, rate %d->%d)",
1200 (char *)&fmt_last.i_codec,
1201 (char *)&id->p_encoder->fmt_in.i_codec,
1202 fmt_last.audio.i_channels,
1203 id->p_encoder->fmt_in.audio.i_channels,
1204 fmt_last.audio.i_rate,
1205 id->p_encoder->fmt_in.audio.i_rate );
1206 filter_chain_AppendFilter( id->p_f_chain, NULL, NULL,
1207 &fmt_last, &id->p_encoder->fmt_in );
1208 fmt_last = *filter_chain_GetFmtOut( id->p_f_chain );
1213 /* Final checks to see if conversions were successful */
1214 if( fmt_last.i_codec != id->p_encoder->fmt_in.i_codec )
1216 msg_Err( p_stream, "no audio filter found "
1217 "(%4.4s->%4.4s, channels %d->%d, rate %d->%d)",
1218 (char *)&fmt_last.i_codec,
1219 (char *)&id->p_encoder->fmt_in.i_codec,
1220 fmt_last.audio.i_channels,
1221 id->p_encoder->fmt_in.audio.i_channels,
1222 fmt_last.audio.i_rate,
1223 id->p_encoder->fmt_in.audio.i_rate );
1224 transcode_audio_close( id );
1225 return VLC_EGENERIC;
1228 /* Load user specified audio filters now */
1229 if( p_sys->psz_af2 )
1231 id->p_uf_chain = filter_chain_New( p_stream, "audio filter2", false,
1232 transcode_audio_filter_allocation_init, NULL, NULL );
1233 filter_chain_Reset( id->p_uf_chain, &fmt_last, &id->p_encoder->fmt_in );
1234 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_af2 );
1235 fmt_last = *filter_chain_GetFmtOut( id->p_uf_chain );
1238 if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels )
1241 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1242 id->p_encoder->p_module = NULL;
1244 /* This might work, but only if the encoder is restarted */
1245 id->p_encoder->fmt_in.audio.i_channels = fmt_last.audio.i_channels;
1246 id->p_encoder->fmt_out.audio.i_channels = fmt_last.audio.i_channels;
1248 id->p_encoder->fmt_in.audio.i_physical_channels =
1249 id->p_encoder->fmt_in.audio.i_original_channels =
1250 fmt_last.audio.i_physical_channels;
1251 id->p_encoder->fmt_out.audio.i_physical_channels =
1252 id->p_encoder->fmt_out.audio.i_original_channels =
1253 fmt_last.audio.i_physical_channels;
1255 msg_Dbg( p_stream, "number of audio channels for mixing changed, "
1256 "trying to reopen the encoder for mixing %i to %i channels",
1257 fmt_last.audio.i_channels,
1258 id->p_encoder->fmt_in.audio.i_channels );
1260 /* reload encoder */
1261 id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1262 id->p_encoder->p_module =
1263 module_Need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1264 if( !id->p_encoder->p_module )
1266 msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)",
1267 p_sys->psz_aenc ? p_sys->psz_aenc : "any",
1268 (char *)&p_sys->i_acodec );
1269 transcode_audio_close( id );
1270 return VLC_EGENERIC;
1272 id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1273 id->p_encoder->fmt_in.audio.i_bitspersample =
1274 aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1276 msg_Err( p_stream, "no audio filter found for mixing from"
1277 " %i to %i channels", fmt_last.audio.i_channels,
1278 id->p_encoder->fmt_in.audio.i_channels );
1280 transcode_audio_close( id );
1281 return VLC_EGENERIC;
1285 if( fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
1287 msg_Err( p_stream, "no audio filter found for resampling from"
1288 " %iHz to %iHz", fmt_last.audio.i_rate,
1289 id->p_encoder->fmt_in.audio.i_rate );
1291 /* FIXME : this might work, but only if the encoder is restarted */
1292 id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;
1293 id->p_encoder->fmt_out.audio.i_rate = fmt_last.audio.i_rate;
1295 transcode_audio_close( id );
1296 return VLC_EGENERIC;
1300 /* FIXME: Hack for mp3 transcoding support */
1301 if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC( 'm','p','3',' ' ) )
1302 id->p_encoder->fmt_out.i_codec = VLC_FOURCC( 'm','p','g','a' );
1307 static void transcode_audio_close( sout_stream_id_t *id )
1309 audio_timer_close( id->p_encoder );
1312 if( id->p_decoder->p_module )
1313 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1314 id->p_decoder->p_module = NULL;
1317 if( id->p_encoder->p_module )
1318 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1319 id->p_encoder->p_module = NULL;
1323 filter_chain_Delete( id->p_f_chain );
1324 if( id->p_uf_chain )
1325 filter_chain_Delete( id->p_uf_chain );
1328 static int transcode_audio_process( sout_stream_t *p_stream,
1329 sout_stream_id_t *id,
1330 block_t *in, block_t **out )
1332 sout_stream_sys_t *p_sys = p_stream->p_sys;
1333 aout_buffer_t *p_audio_buf;
1334 block_t *p_block, *p_audio_block;
1337 while( (p_audio_buf = id->p_decoder->pf_decode_audio( id->p_decoder,
1340 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_AUDIO, 1 );
1341 if( p_sys->b_master_sync )
1343 mtime_t i_dts = date_Get( &id->interpolated_pts ) + 1;
1344 if ( p_audio_buf->start_date - i_dts > MASTER_SYNC_MAX_DRIFT
1345 || p_audio_buf->start_date - i_dts < -MASTER_SYNC_MAX_DRIFT )
1347 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1348 date_Set( &id->interpolated_pts, p_audio_buf->start_date );
1349 i_dts = p_audio_buf->start_date + 1;
1351 p_sys->i_master_drift = p_audio_buf->start_date - i_dts;
1352 date_Increment( &id->interpolated_pts, p_audio_buf->i_nb_samples );
1353 p_audio_buf->start_date -= p_sys->i_master_drift;
1354 p_audio_buf->end_date -= p_sys->i_master_drift;
1357 p_audio_block = p_audio_buf->p_sys;
1358 p_audio_block->i_buffer = p_audio_buf->i_nb_bytes;
1359 p_audio_block->i_dts = p_audio_block->i_pts =
1360 p_audio_buf->start_date;
1361 p_audio_block->i_length = p_audio_buf->end_date -
1362 p_audio_buf->start_date;
1363 p_audio_block->i_samples = p_audio_buf->i_nb_samples;
1365 /* Run filter chain */
1366 p_audio_block = filter_chain_AudioFilter( id->p_f_chain, p_audio_block );
1367 if( id->p_uf_chain )
1368 p_audio_block = filter_chain_AudioFilter( id->p_uf_chain, p_audio_block );
1369 assert( p_audio_block );
1371 p_audio_buf->p_buffer = p_audio_block->p_buffer;
1372 p_audio_buf->i_nb_bytes = p_audio_block->i_buffer;
1373 p_audio_buf->i_nb_samples = p_audio_block->i_samples;
1374 p_audio_buf->start_date = p_audio_block->i_dts;
1375 p_audio_buf->end_date = p_audio_block->i_dts + p_audio_block->i_length;
1377 audio_timer_start( id->p_encoder );
1378 p_block = id->p_encoder->pf_encode_audio( id->p_encoder, p_audio_buf );
1379 audio_timer_stop( id->p_encoder );
1381 block_ChainAppend( out, p_block );
1382 block_Release( p_audio_block );
1383 free( p_audio_buf );
1389 static void audio_release_buffer( aout_buffer_t *p_buffer )
1391 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1395 static aout_buffer_t *audio_new_buffer( decoder_t *p_dec, int i_samples )
1397 aout_buffer_t *p_buffer;
1401 if( p_dec->fmt_out.audio.i_bitspersample )
1403 i_size = i_samples * p_dec->fmt_out.audio.i_bitspersample / 8 *
1404 p_dec->fmt_out.audio.i_channels;
1406 else if( p_dec->fmt_out.audio.i_bytes_per_frame &&
1407 p_dec->fmt_out.audio.i_frame_length )
1409 i_size = i_samples * p_dec->fmt_out.audio.i_bytes_per_frame /
1410 p_dec->fmt_out.audio.i_frame_length;
1414 i_size = i_samples * 4 * p_dec->fmt_out.audio.i_channels;
1417 p_buffer = malloc( sizeof(aout_buffer_t) );
1418 if( !p_buffer ) return NULL;
1419 p_buffer->b_discontinuity = false;
1420 p_buffer->pf_release = audio_release_buffer;
1421 p_buffer->p_sys = p_block = block_New( p_dec, i_size );
1423 p_buffer->p_buffer = p_block->p_buffer;
1424 p_buffer->i_size = p_buffer->i_nb_bytes = p_block->i_buffer;
1425 p_buffer->i_nb_samples = i_samples;
1426 p_block->i_samples = i_samples;
1431 static void audio_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
1434 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1442 static int transcode_video_filter_allocation_init( filter_t *p_filter,
1445 sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_data;
1448 p_filter->pf_vout_buffer_new = video_new_buffer_filter;
1449 p_filter->pf_vout_buffer_del = video_del_buffer_filter;
1451 p_filter->p_owner = malloc( sizeof(filter_owner_sys_t) );
1452 if( !p_filter->p_owner )
1453 return VLC_EGENERIC;
1455 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1456 p_filter->p_owner->pp_pics[i] = 0;
1457 p_filter->p_owner->p_sys = p_sys;
1462 static void transcode_video_filter_allocation_clear( filter_t *p_filter )
1466 /* Clean-up pictures ring buffer */
1467 for( j = 0; j < PICTURE_RING_SIZE; j++ )
1469 if( p_filter->p_owner->pp_pics[j] )
1470 video_del_buffer( VLC_OBJECT(p_filter),
1471 p_filter->p_owner->pp_pics[j] );
1473 free( p_filter->p_owner );
1476 static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
1478 sout_stream_sys_t *p_sys = p_stream->p_sys;
1482 * Initialization of decoder structures
1484 id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1485 id->p_decoder->fmt_out.i_extra = 0;
1486 id->p_decoder->fmt_out.p_extra = 0;
1487 id->p_decoder->pf_decode_video = NULL;
1488 id->p_decoder->pf_get_cc = NULL;
1489 id->p_decoder->pf_get_cc = 0;
1490 id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
1491 id->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder;
1492 id->p_decoder->pf_picture_link = video_link_picture_decoder;
1493 id->p_decoder->pf_picture_unlink = video_unlink_picture_decoder;
1494 id->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) );
1495 if( !id->p_decoder->p_owner )
1496 return VLC_EGENERIC;
1498 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1499 id->p_decoder->p_owner->pp_pics[i] = 0;
1500 id->p_decoder->p_owner->p_sys = p_sys;
1501 /* id->p_decoder->p_cfg = p_sys->p_video_cfg; */
1503 id->p_decoder->p_module =
1504 module_Need( id->p_decoder, "decoder", "$codec", 0 );
1506 if( !id->p_decoder->p_module )
1508 msg_Err( p_stream, "cannot find video decoder" );
1509 free( id->p_decoder->p_owner );
1510 return VLC_EGENERIC;
1515 * Because some info about the decoded input will only be available
1516 * once the first frame is decoded, we actually only test the availability
1517 * of the encoder here.
1520 /* Initialization of encoder format structures */
1521 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1522 id->p_decoder->fmt_out.i_codec );
1523 id->p_encoder->fmt_in.video.i_chroma = id->p_decoder->fmt_out.i_codec;
1525 /* The dimensions will be set properly later on.
1526 * Just put sensible values so we can test an encoder is available. */
1527 id->p_encoder->fmt_in.video.i_width =
1528 id->p_encoder->fmt_out.video.i_width ?:
1529 id->p_decoder->fmt_in.video.i_width ?: 16;
1530 id->p_encoder->fmt_in.video.i_height =
1531 id->p_encoder->fmt_out.video.i_height ?:
1532 id->p_decoder->fmt_in.video.i_height ?: 16;
1533 id->p_encoder->fmt_in.video.i_frame_rate = ENC_FRAMERATE;
1534 id->p_encoder->fmt_in.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1536 id->p_encoder->i_threads = p_sys->i_threads;
1537 id->p_encoder->p_cfg = p_sys->p_video_cfg;
1539 id->p_encoder->p_module =
1540 module_Need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1541 if( !id->p_encoder->p_module )
1543 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1544 p_sys->psz_venc ? p_sys->psz_venc : "any",
1545 (char *)&p_sys->i_vcodec );
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;
1552 /* Close the encoder.
1553 * We'll open it only when we have the first frame. */
1554 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1555 if( id->p_encoder->fmt_out.p_extra )
1557 free( id->p_encoder->fmt_out.p_extra );
1558 id->p_encoder->fmt_out.p_extra = NULL;
1559 id->p_encoder->fmt_out.i_extra = 0;
1561 id->p_encoder->p_module = NULL;
1563 if( p_sys->i_threads >= 1 )
1565 int i_priority = p_sys->b_high_priority ? VLC_THREAD_PRIORITY_OUTPUT :
1566 VLC_THREAD_PRIORITY_VIDEO;
1567 p_sys->id_video = id;
1568 vlc_mutex_init( &p_sys->lock_out );
1569 vlc_cond_init( p_stream, &p_sys->cond );
1570 memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) );
1571 p_sys->i_first_pic = 0;
1572 p_sys->i_last_pic = 0;
1573 p_sys->p_buffers = NULL;
1574 p_sys->b_die = p_sys->b_error = 0;
1575 if( vlc_thread_create( p_sys, "encoder", EncoderThread, i_priority,
1578 msg_Err( p_stream, "cannot spawn encoder thread" );
1579 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1580 id->p_decoder->p_module = 0;
1581 free( id->p_decoder->p_owner );
1582 return VLC_EGENERIC;
1589 static void transcode_video_encoder_init( sout_stream_t *p_stream,
1590 sout_stream_id_t *id )
1592 sout_stream_sys_t *p_sys = p_stream->p_sys;
1594 /* Calculate scaling
1595 * width/height of source */
1596 int i_src_width = id->p_decoder->fmt_out.video.i_width;
1597 int i_src_height = id->p_decoder->fmt_out.video.i_height;
1599 /* with/height scaling */
1600 float f_scale_width = 1;
1601 float f_scale_height = 1;
1603 /* width/height of output stream */
1608 float f_aspect = (float)id->p_decoder->fmt_out.video.i_aspect /
1611 msg_Dbg( p_stream, "decoder aspect is %i:%i",
1612 id->p_decoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1614 /* Change f_aspect from source frame to source pixel */
1615 f_aspect = f_aspect * i_src_height / i_src_width;
1616 msg_Dbg( p_stream, "source pixel aspect is %f:1", f_aspect );
1618 /* Calculate scaling factor for specified parameters */
1619 if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1620 id->p_encoder->fmt_out.video.i_height <= 0 && p_sys->f_scale )
1622 /* Global scaling. Make sure width will remain a factor of 16 */
1625 int i_new_width = i_src_width * p_sys->f_scale;
1627 if( i_new_width % 16 <= 7 && i_new_width >= 16 )
1628 i_new_width -= i_new_width % 16;
1630 i_new_width += 16 - i_new_width % 16;
1632 f_real_scale = (float)( i_new_width ) / (float) i_src_width;
1634 i_new_height = __MAX( 16, i_src_height * (float)f_real_scale );
1636 f_scale_width = f_real_scale;
1637 f_scale_height = (float) i_new_height / (float) i_src_height;
1639 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1640 id->p_encoder->fmt_out.video.i_height <= 0 )
1642 /* Only width specified */
1643 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1644 f_scale_height = f_scale_width;
1646 else if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1647 id->p_encoder->fmt_out.video.i_height > 0 )
1649 /* Only height specified */
1650 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1651 f_scale_width = f_scale_height;
1653 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1654 id->p_encoder->fmt_out.video.i_height > 0 )
1656 /* Width and height specified */
1657 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1658 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1661 /* check maxwidth and maxheight
1663 if( p_sys->i_maxwidth && f_scale_width > (float)p_sys->i_maxwidth /
1666 f_scale_width = (float)p_sys->i_maxwidth / i_src_width;
1669 if( p_sys->i_maxheight && f_scale_height > (float)p_sys->i_maxheight /
1672 f_scale_height = (float)p_sys->i_maxheight / i_src_height;
1676 /* Change aspect ratio from source pixel to scaled pixel */
1677 f_aspect = f_aspect * f_scale_height / f_scale_width;
1678 msg_Dbg( p_stream, "scaled pixel aspect is %f:1", f_aspect );
1680 /* f_scale_width and f_scale_height are now final */
1681 /* Calculate width, height from scaling
1682 * Make sure its multiple of 2
1684 i_dst_width = 2 * (int)(f_scale_width*i_src_width/2+0.5);
1685 i_dst_height = 2 * (int)(f_scale_height*i_src_height/2+0.5);
1687 /* Change aspect ratio from scaled pixel to output frame */
1688 f_aspect = f_aspect * i_dst_width / i_dst_height;
1690 /* Store calculated values */
1691 id->p_encoder->fmt_out.video.i_width =
1692 id->p_encoder->fmt_out.video.i_visible_width = i_dst_width;
1693 id->p_encoder->fmt_out.video.i_height =
1694 id->p_encoder->fmt_out.video.i_visible_height = i_dst_height;
1696 id->p_encoder->fmt_in.video.i_width =
1697 id->p_encoder->fmt_in.video.i_visible_width = i_dst_width;
1698 id->p_encoder->fmt_in.video.i_height =
1699 id->p_encoder->fmt_in.video.i_visible_height = i_dst_height;
1701 msg_Dbg( p_stream, "source %ix%i, destination %ix%i",
1702 i_src_width, i_src_height,
1703 i_dst_width, i_dst_height
1706 /* Handle frame rate conversion */
1707 if( !id->p_encoder->fmt_out.video.i_frame_rate ||
1708 !id->p_encoder->fmt_out.video.i_frame_rate_base )
1710 if( id->p_decoder->fmt_out.video.i_frame_rate &&
1711 id->p_decoder->fmt_out.video.i_frame_rate_base )
1713 id->p_encoder->fmt_out.video.i_frame_rate =
1714 id->p_decoder->fmt_out.video.i_frame_rate;
1715 id->p_encoder->fmt_out.video.i_frame_rate_base =
1716 id->p_decoder->fmt_out.video.i_frame_rate_base;
1720 /* Pick a sensible default value */
1721 id->p_encoder->fmt_out.video.i_frame_rate = ENC_FRAMERATE;
1722 id->p_encoder->fmt_out.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1726 id->p_encoder->fmt_in.video.i_frame_rate =
1727 id->p_encoder->fmt_out.video.i_frame_rate;
1728 id->p_encoder->fmt_in.video.i_frame_rate_base =
1729 id->p_encoder->fmt_out.video.i_frame_rate_base;
1731 date_Init( &id->interpolated_pts,
1732 id->p_encoder->fmt_out.video.i_frame_rate,
1733 id->p_encoder->fmt_out.video.i_frame_rate_base );
1735 /* Check whether a particular aspect ratio was requested */
1736 if( !id->p_encoder->fmt_out.video.i_aspect )
1738 id->p_encoder->fmt_out.video.i_aspect =
1739 (int)( f_aspect * VOUT_ASPECT_FACTOR + 0.5 );
1741 id->p_encoder->fmt_in.video.i_aspect =
1742 id->p_encoder->fmt_out.video.i_aspect;
1744 msg_Dbg( p_stream, "encoder aspect is %i:%i",
1745 id->p_encoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1747 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1750 static int transcode_video_encoder_open( sout_stream_t *p_stream,
1751 sout_stream_id_t *id )
1753 sout_stream_sys_t *p_sys = p_stream->p_sys;
1756 msg_Dbg( p_stream, "destination (after video filters) %ix%i",
1757 id->p_encoder->fmt_in.video.i_width,
1758 id->p_encoder->fmt_in.video.i_height );
1760 id->p_encoder->p_module =
1761 module_Need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1762 if( !id->p_encoder->p_module )
1764 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1765 p_sys->psz_venc ? p_sys->psz_venc : "any",
1766 (char *)&p_sys->i_vcodec );
1767 return VLC_EGENERIC;
1770 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1772 /* Hack for mp2v/mp1v transcoding support */
1773 if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','1','v') ||
1774 id->p_encoder->fmt_out.i_codec == VLC_FOURCC('m','p','2','v') )
1776 id->p_encoder->fmt_out.i_codec = VLC_FOURCC('m','p','g','v');
1779 id->id = p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out,
1780 &id->p_encoder->fmt_out );
1783 msg_Err( p_stream, "cannot add this stream" );
1784 return VLC_EGENERIC;
1790 static void transcode_video_close( sout_stream_t *p_stream,
1791 sout_stream_id_t *id )
1795 if( p_stream->p_sys->i_threads >= 1 )
1797 vlc_mutex_lock( &p_stream->p_sys->lock_out );
1798 vlc_object_kill( p_stream->p_sys );
1799 vlc_cond_signal( &p_stream->p_sys->cond );
1800 vlc_mutex_unlock( &p_stream->p_sys->lock_out );
1801 vlc_thread_join( p_stream->p_sys );
1802 vlc_mutex_destroy( &p_stream->p_sys->lock_out );
1803 vlc_cond_destroy( &p_stream->p_sys->cond );
1806 video_timer_close( id->p_encoder );
1809 if( id->p_decoder->p_module )
1810 module_Unneed( id->p_decoder, id->p_decoder->p_module );
1812 if( id->p_decoder->p_owner )
1814 /* Clean-up pictures ring buffer */
1815 for( i = 0; i < PICTURE_RING_SIZE; i++ )
1817 if( id->p_decoder->p_owner->pp_pics[i] )
1818 video_del_buffer( VLC_OBJECT(id->p_decoder),
1819 id->p_decoder->p_owner->pp_pics[i] );
1821 free( id->p_decoder->p_owner );
1825 if( id->p_encoder->p_module )
1826 module_Unneed( id->p_encoder, id->p_encoder->p_module );
1830 filter_chain_Delete( id->p_f_chain );
1831 if( id->p_uf_chain )
1832 filter_chain_Delete( id->p_uf_chain );
1835 static int transcode_video_process( sout_stream_t *p_stream,
1836 sout_stream_id_t *id,
1837 block_t *in, block_t **out )
1839 sout_stream_sys_t *p_sys = p_stream->p_sys;
1840 int i_duplicate = 1;
1841 picture_t *p_pic, *p_pic2 = NULL;
1844 while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
1846 subpicture_t *p_subpic = NULL;
1848 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_VIDEO, 1 );
1850 if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )
1852 mtime_t current_date = mdate();
1853 if( current_date + 50000 > p_pic->date )
1855 msg_Dbg( p_stream, "late picture skipped (%"PRId64")",
1856 current_date + 50000 - p_pic->date );
1857 p_pic->pf_release( p_pic );
1862 if( p_sys->b_master_sync )
1864 mtime_t i_video_drift;
1865 mtime_t i_master_drift = p_sys->i_master_drift;
1868 i_pts = date_Get( &id->interpolated_pts ) + 1;
1869 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1870 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
1872 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1873 date_Set( &id->interpolated_pts, p_pic->date );
1874 i_pts = p_pic->date + 1;
1876 i_video_drift = p_pic->date - i_pts;
1879 /* Set the pts of the frame being encoded */
1880 p_pic->date = i_pts;
1882 if( i_video_drift < (i_master_drift - 50000) )
1885 msg_Dbg( p_stream, "dropping frame (%i)",
1886 (int)(i_video_drift - i_master_drift) );
1888 p_pic->pf_release( p_pic );
1891 else if( i_video_drift > (i_master_drift + 50000) )
1894 msg_Dbg( p_stream, "adding frame (%i)",
1895 (int)(i_video_drift - i_master_drift) );
1901 if( !id->p_encoder->p_module )
1903 transcode_video_encoder_init( p_stream, id );
1905 id->p_f_chain = filter_chain_New( p_stream, "video filter2",
1907 transcode_video_filter_allocation_init,
1908 transcode_video_filter_allocation_clear,
1912 if( p_stream->p_sys->b_deinterlace )
1914 filter_chain_AppendFilter( id->p_f_chain,
1915 p_sys->psz_deinterlace,
1916 p_sys->p_deinterlace_cfg,
1917 &id->p_decoder->fmt_out,
1918 &id->p_decoder->fmt_out );
1921 /* Take care of the scaling and chroma conversions */
1922 if( ( id->p_decoder->fmt_out.video.i_chroma !=
1923 id->p_encoder->fmt_in.video.i_chroma ) ||
1924 ( id->p_decoder->fmt_out.video.i_width !=
1925 id->p_encoder->fmt_in.video.i_width ) ||
1926 ( id->p_decoder->fmt_out.video.i_height !=
1927 id->p_encoder->fmt_in.video.i_height ) )
1929 filter_chain_AppendFilter( id->p_f_chain,
1931 &id->p_decoder->fmt_out,
1932 &id->p_encoder->fmt_in );
1935 if( p_sys->psz_vf2 )
1937 const es_format_t *p_fmt_out;
1938 id->p_uf_chain = filter_chain_New( p_stream, "video filter2",
1940 transcode_video_filter_allocation_init,
1941 transcode_video_filter_allocation_clear,
1943 filter_chain_Reset( id->p_uf_chain, &id->p_encoder->fmt_in,
1944 &id->p_encoder->fmt_in );
1945 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_vf2 );
1946 p_fmt_out = filter_chain_GetFmtOut( id->p_uf_chain );
1947 es_format_Copy( &id->p_encoder->fmt_in, p_fmt_out );
1948 id->p_encoder->fmt_out.video.i_width =
1949 id->p_encoder->fmt_in.video.i_width;
1950 id->p_encoder->fmt_out.video.i_height =
1951 id->p_encoder->fmt_in.video.i_height;
1954 if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS )
1956 p_pic->pf_release( p_pic );
1957 transcode_video_close( p_stream, id );
1958 id->b_transcode = false;
1959 return VLC_EGENERIC;
1963 /* Run filter chain */
1965 p_pic = filter_chain_VideoFilter( id->p_f_chain, p_pic );
1971 /* Check if we have a subpicture to overlay */
1974 p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date,
1975 false /* Fixme: check if stream is paused */ );
1976 /* TODO: get another pic */
1979 /* Overlay subpicture */
1982 int i_scale_width, i_scale_height;
1985 i_scale_width = id->p_encoder->fmt_in.video.i_width * 1000 /
1986 id->p_decoder->fmt_out.video.i_width;
1987 i_scale_height = id->p_encoder->fmt_in.video.i_height * 1000 /
1988 id->p_decoder->fmt_out.video.i_height;
1990 if( p_pic->i_refcount && !filter_chain_GetLength( id->p_f_chain ) )
1992 /* We can't modify the picture, we need to duplicate it */
1993 picture_t *p_tmp = video_new_buffer_decoder( id->p_decoder );
1996 vout_CopyPicture( p_stream, p_tmp, p_pic );
1997 p_pic->pf_release( p_pic );
2002 if( filter_chain_GetLength( id->p_f_chain ) > 0 )
2003 fmt = filter_chain_GetFmtOut( id->p_f_chain )->video;
2005 fmt = id->p_decoder->fmt_out.video;
2007 /* FIXME (shouldn't have to be done here) */
2008 fmt.i_sar_num = fmt.i_aspect * fmt.i_height / fmt.i_width;
2009 fmt.i_sar_den = VOUT_ASPECT_FACTOR;
2011 spu_RenderSubpictures( p_sys->p_spu, &fmt, p_pic, p_pic, p_subpic,
2012 i_scale_width, i_scale_height );
2015 /* Run user specified filter chain */
2016 if( id->p_uf_chain )
2017 p_pic = filter_chain_VideoFilter( id->p_uf_chain, p_pic );
2019 if( p_sys->i_threads == 0 )
2023 video_timer_start( id->p_encoder );
2024 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2025 video_timer_stop( id->p_encoder );
2027 block_ChainAppend( out, p_block );
2030 if( p_sys->b_master_sync )
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 );
2043 if( p_sys->b_master_sync && i_duplicate > 1 )
2045 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
2046 if( (p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT)
2047 || ((p_pic->date - i_pts) < -MASTER_SYNC_MAX_DRIFT) )
2049 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
2050 date_Set( &id->interpolated_pts, p_pic->date );
2051 i_pts = p_pic->date + 1;
2053 date_Increment( &id->interpolated_pts, 1 );
2055 if( p_sys->i_threads >= 1 )
2057 /* We can't modify the picture, we need to duplicate it */
2058 p_pic2 = video_new_buffer_decoder( id->p_decoder );
2059 if( p_pic2 != NULL )
2061 vout_CopyPicture( p_stream, p_pic2, p_pic );
2062 p_pic2->date = i_pts;
2068 p_pic->date = i_pts;
2069 video_timer_start( id->p_encoder );
2070 p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);
2071 video_timer_stop( id->p_encoder );
2072 block_ChainAppend( out, p_block );
2076 if( p_sys->i_threads == 0 )
2078 p_pic->pf_release( p_pic );
2082 vlc_mutex_lock( &p_sys->lock_out );
2083 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
2084 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2085 *out = p_sys->p_buffers;
2086 p_sys->p_buffers = NULL;
2087 if( p_pic2 != NULL )
2089 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic2;
2090 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2092 vlc_cond_signal( &p_sys->cond );
2093 vlc_mutex_unlock( &p_sys->lock_out );
2100 static void* EncoderThread( vlc_object_t* p_this )
2102 sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_this;
2103 sout_stream_id_t *id = p_sys->id_video;
2105 int canc = vlc_savecancel ();
2107 while( vlc_object_alive (p_sys) && !p_sys->b_error )
2111 vlc_mutex_lock( &p_sys->lock_out );
2112 while( p_sys->i_last_pic == p_sys->i_first_pic )
2114 vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );
2115 if( !vlc_object_alive (p_sys) || p_sys->b_error ) break;
2117 if( !vlc_object_alive (p_sys) || p_sys->b_error )
2119 vlc_mutex_unlock( &p_sys->lock_out );
2123 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2124 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2125 vlc_mutex_unlock( &p_sys->lock_out );
2127 video_timer_start( id->p_encoder );
2128 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2129 video_timer_stop( id->p_encoder );
2131 vlc_mutex_lock( &p_sys->lock_out );
2132 block_ChainAppend( &p_sys->p_buffers, p_block );
2134 vlc_mutex_unlock( &p_sys->lock_out );
2135 p_pic->pf_release( p_pic );
2138 while( p_sys->i_last_pic != p_sys->i_first_pic )
2140 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2141 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2142 p_pic->pf_release( p_pic );
2144 block_ChainRelease( p_sys->p_buffers );
2146 vlc_restorecancel (canc);
2150 struct picture_sys_t
2152 vlc_object_t *p_owner;
2155 static void video_release_buffer( picture_t *p_pic )
2157 if( p_pic && !p_pic->i_refcount && p_pic->pf_release && p_pic->p_sys )
2159 video_del_buffer_decoder( (decoder_t *)p_pic->p_sys->p_owner, p_pic );
2161 else if( p_pic && p_pic->i_refcount > 0 ) p_pic->i_refcount--;
2164 static picture_t *video_new_buffer( vlc_object_t *p_this, picture_t **pp_ring,
2165 sout_stream_sys_t *p_sys )
2167 decoder_t *p_dec = (decoder_t *)p_this;
2171 /* Find an empty space in the picture ring buffer */
2172 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2174 if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2176 pp_ring[i]->i_status = RESERVED_PICTURE;
2180 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2182 if( pp_ring[i] == 0 ) break;
2185 if( i == PICTURE_RING_SIZE && p_sys->i_threads >= 1 )
2187 int i_first_pic = p_sys->i_first_pic;
2189 if( p_sys->i_first_pic != p_sys->i_last_pic )
2191 /* Encoder still has stuff to encode, wait to clear-up the list */
2192 while( p_sys->i_first_pic == i_first_pic )
2196 /* Find an empty space in the picture ring buffer */
2197 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2199 if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )
2201 pp_ring[i]->i_status = RESERVED_PICTURE;
2205 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2207 if( pp_ring[i] == 0 ) break;
2211 if( i == PICTURE_RING_SIZE )
2213 msg_Err( p_this, "decoder/filter is leaking pictures, "
2214 "resetting its ring buffer" );
2216 for( i = 0; i < PICTURE_RING_SIZE; i++ )
2218 pp_ring[i]->pf_release( pp_ring[i] );
2224 p_pic = malloc( sizeof(picture_t) );
2225 if( !p_pic ) return NULL;
2226 p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
2227 vout_AllocatePicture( VLC_OBJECT(p_dec), p_pic,
2228 p_dec->fmt_out.video.i_chroma,
2229 p_dec->fmt_out.video.i_width,
2230 p_dec->fmt_out.video.i_height,
2231 p_dec->fmt_out.video.i_aspect );
2233 if( !p_pic->i_planes )
2239 p_pic->pf_release = video_release_buffer;
2240 p_pic->p_sys = malloc( sizeof(picture_sys_t) );
2247 p_pic->p_sys->p_owner = p_this;
2248 p_pic->i_status = RESERVED_PICTURE;
2254 static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
2256 return video_new_buffer( VLC_OBJECT(p_dec),
2257 p_dec->p_owner->pp_pics, p_dec->p_owner->p_sys );
2260 static picture_t *video_new_buffer_filter( filter_t *p_filter )
2262 return video_new_buffer( VLC_OBJECT(p_filter),
2263 p_filter->p_owner->pp_pics,
2264 p_filter->p_owner->p_sys );
2267 static void video_del_buffer( vlc_object_t *p_this, picture_t *p_pic )
2272 free( p_pic->p_data_orig );
2273 free( p_pic->p_sys );
2278 static void video_del_buffer_decoder( decoder_t *p_decoder, picture_t *p_pic )
2280 VLC_UNUSED(p_decoder);
2281 p_pic->i_refcount = 0;
2282 p_pic->i_status = DESTROYED_PICTURE;
2285 static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic )
2287 VLC_UNUSED(p_filter);
2288 p_pic->i_refcount = 0;
2289 p_pic->i_status = DESTROYED_PICTURE;
2292 static void video_link_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2295 p_pic->i_refcount++;
2298 static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2301 video_release_buffer( p_pic );
2307 static subpicture_t *spu_new_buffer( decoder_t * );
2308 static void spu_del_buffer( decoder_t *, subpicture_t * );
2310 static int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2312 sout_stream_sys_t *p_sys = p_stream->p_sys;
2318 /* Initialization of decoder structures */
2319 id->p_decoder->pf_decode_sub = NULL;
2320 id->p_decoder->pf_spu_buffer_new = spu_new_buffer;
2321 id->p_decoder->pf_spu_buffer_del = spu_del_buffer;
2322 id->p_decoder->p_owner = (decoder_owner_sys_t *)p_stream;
2323 /* id->p_decoder->p_cfg = p_sys->p_spu_cfg; */
2325 id->p_decoder->p_module =
2326 module_Need( id->p_decoder, "decoder", "$codec", 0 );
2328 if( !id->p_decoder->p_module )
2330 msg_Err( p_stream, "cannot find spu decoder" );
2331 return VLC_EGENERIC;
2334 if( !p_sys->b_soverlay )
2337 /* Initialization of encoder format structures */
2338 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2339 id->p_decoder->fmt_in.i_codec );
2341 id->p_encoder->p_cfg = p_sys->p_spu_cfg;
2343 id->p_encoder->p_module =
2344 module_Need( id->p_encoder, "encoder", p_sys->psz_senc, true );
2346 if( !id->p_encoder->p_module )
2348 module_Unneed( id->p_decoder, id->p_decoder->p_module );
2349 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_senc );
2350 return VLC_EGENERIC;
2356 p_sys->p_spu = spu_Create( p_stream );
2357 spu_Init( p_sys->p_spu );
2363 static void transcode_spu_close( sout_stream_id_t *id)
2366 if( id->p_decoder->p_module )
2367 module_Unneed( id->p_decoder, id->p_decoder->p_module );
2370 if( id->p_encoder->p_module )
2371 module_Unneed( id->p_encoder, id->p_encoder->p_module );
2374 static int transcode_spu_process( sout_stream_t *p_stream,
2375 sout_stream_id_t *id,
2376 block_t *in, block_t **out )
2378 sout_stream_sys_t *p_sys = p_stream->p_sys;
2379 subpicture_t *p_subpic;
2382 p_subpic = id->p_decoder->pf_decode_sub( id->p_decoder, &in );
2384 return VLC_EGENERIC;
2386 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_SUBTITLE, 1 );
2388 if( p_sys->b_master_sync && p_sys->i_master_drift )
2390 p_subpic->i_start -= p_sys->i_master_drift;
2391 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2394 if( p_sys->b_soverlay )
2396 spu_DisplaySubpicture( p_sys->p_spu, p_subpic );
2402 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2403 spu_del_buffer( id->p_decoder, p_subpic );
2406 block_ChainAppend( out, p_block );
2411 return VLC_EGENERIC;
2414 static subpicture_t *spu_new_buffer( decoder_t *p_dec )
2416 sout_stream_t *p_stream = (sout_stream_t *)p_dec->p_owner;
2417 return spu_CreateSubpicture( p_stream->p_sys->p_spu );
2420 static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
2422 sout_stream_t *p_stream = (sout_stream_t *)p_dec->p_owner;
2423 spu_DestroySubpicture( p_stream->p_sys->p_spu, p_subpic );
2429 static int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2431 sout_stream_sys_t *p_sys = p_stream->p_sys;
2433 id->p_decoder->fmt_in.i_cat = SPU_ES;
2434 id->p_encoder->fmt_out.psz_language = strdup( "osd" );
2436 if( p_sys->i_osdcodec != 0 || p_sys->psz_osdenc )
2438 msg_Dbg( p_stream, "creating osdmenu transcoding from fcc=`%4.4s' "
2439 "to fcc=`%4.4s'", (char*)&id->p_encoder->fmt_out.i_codec,
2440 (char*)&p_sys->i_osdcodec );
2442 /* Complete destination format */
2443 id->p_encoder->fmt_out.i_codec = p_sys->i_osdcodec;
2446 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2447 VLC_FOURCC('Y','U','V','A') );
2448 id->p_encoder->fmt_in.psz_language = strdup( "osd" );
2450 id->p_encoder->p_cfg = p_sys->p_osd_cfg;
2452 id->p_encoder->p_module =
2453 module_Need( id->p_encoder, "encoder", p_sys->psz_osdenc, true );
2455 if( !id->p_encoder->p_module )
2457 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_osdenc );
2461 /* open output stream */
2462 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_encoder->fmt_out );
2463 id->b_transcode = true;
2465 if( !id->id ) goto error;
2469 msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
2470 (char*)&id->p_decoder->fmt_out.i_codec );
2471 id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_decoder->fmt_out );
2472 id->b_transcode = false;
2474 if( !id->id ) goto error;
2479 p_sys->p_spu = spu_Create( p_stream );
2480 spu_Init( p_sys->p_spu );
2486 msg_Err( p_stream, "starting osd encoding thread failed" );
2487 if( id->p_encoder->p_module )
2488 module_Unneed( id->p_encoder, id->p_encoder->p_module );
2489 p_sys->b_osd = false;
2490 return VLC_EGENERIC;
2493 static void transcode_osd_close( sout_stream_t *p_stream, sout_stream_id_t *id)
2495 sout_stream_sys_t *p_sys = p_stream->p_sys;
2500 if( id->p_encoder->p_module )
2501 module_Unneed( id->p_encoder, id->p_encoder->p_module );
2503 p_sys->b_osd = false;
2506 static int transcode_osd_process( sout_stream_t *p_stream,
2507 sout_stream_id_t *id,
2508 block_t *in, block_t **out )
2510 sout_stream_sys_t *p_sys = p_stream->p_sys;
2511 subpicture_t *p_subpic = NULL;
2513 /* Check if we have a subpicture to send */
2514 if( p_sys->p_spu && in->i_dts > 0)
2516 p_subpic = spu_SortSubpictures( p_sys->p_spu, in->i_dts, false );
2520 msg_Warn( p_stream, "spu channel not initialized, doing it now" );
2523 p_sys->p_spu = spu_Create( p_stream );
2524 spu_Init( p_sys->p_spu );
2530 block_t *p_block = NULL;
2532 if( p_sys->b_master_sync && p_sys->i_master_drift )
2534 p_subpic->i_start -= p_sys->i_master_drift;
2535 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2538 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2539 spu_DestroySubpicture( p_sys->p_spu, p_subpic );
2542 p_block->i_dts = p_block->i_pts = in->i_dts;
2543 block_ChainAppend( out, p_block );
2547 return VLC_EGENERIC;