1 /*****************************************************************************
2 * transcode.c: transcoding stream output module
3 *****************************************************************************
4 * Copyright (C) 2003-2008 the VideoLAN team
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8 * Gildas Bazin <gbazin@videolan.org>
9 * Jean-Paul Saman <jpsaman #_at_# m2x dot nl>
10 * Antoine Cellerier <dionoea at videolan dot org>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25 *****************************************************************************/
27 /*****************************************************************************
29 *****************************************************************************/
34 #include <vlc_common.h>
35 #include <vlc_plugin.h>
36 #include <vlc_input.h>
40 #include <vlc_codec.h>
42 #include <vlc_block.h>
43 #include <vlc_filter.h>
48 #define MASTER_SYNC_MAX_DRIFT 100000
52 /*****************************************************************************
54 *****************************************************************************/
55 #define VENC_TEXT N_("Video encoder")
56 #define VENC_LONGTEXT N_( \
57 "This is the video encoder module that will be used (and its associated "\
59 #define VCODEC_TEXT N_("Destination video codec")
60 #define VCODEC_LONGTEXT N_( \
61 "This is the video codec that will be used.")
62 #define VB_TEXT N_("Video bitrate")
63 #define VB_LONGTEXT N_( \
64 "Target bitrate of the transcoded video stream." )
65 #define SCALE_TEXT N_("Video scaling")
66 #define SCALE_LONGTEXT N_( \
67 "Scale factor to apply to the video while transcoding (eg: 0.25)")
68 #define FPS_TEXT N_("Video frame-rate")
69 #define FPS_LONGTEXT N_( \
70 "Target output frame rate for the video stream." )
71 #define DEINTERLACE_TEXT N_("Deinterlace video")
72 #define DEINTERLACE_LONGTEXT N_( \
73 "Deinterlace the video before encoding." )
74 #define DEINTERLACE_MODULE_TEXT N_("Deinterlace module")
75 #define DEINTERLACE_MODULE_LONGTEXT N_( \
76 "Specify the deinterlace module to use." )
77 #define WIDTH_TEXT N_("Video width")
78 #define WIDTH_LONGTEXT N_( \
79 "Output video width." )
80 #define HEIGHT_TEXT N_("Video height")
81 #define HEIGHT_LONGTEXT N_( \
82 "Output video height." )
83 #define MAXWIDTH_TEXT N_("Maximum video width")
84 #define MAXWIDTH_LONGTEXT N_( \
85 "Maximum output video width." )
86 #define MAXHEIGHT_TEXT N_("Maximum video height")
87 #define MAXHEIGHT_LONGTEXT N_( \
88 "Maximum output video height." )
89 #define VFILTER_TEXT N_("Video filter")
90 #define VFILTER_LONGTEXT N_( \
91 "Video filters will be applied to the video streams (after overlays " \
92 "are applied). You must enter a comma-separated list of filters." )
94 #define AENC_TEXT N_("Audio encoder")
95 #define AENC_LONGTEXT N_( \
96 "This is the audio encoder module that will be used (and its associated "\
98 #define ACODEC_TEXT N_("Destination audio codec")
99 #define ACODEC_LONGTEXT N_( \
100 "This is the audio codec that will be used.")
101 #define AB_TEXT N_("Audio bitrate")
102 #define AB_LONGTEXT N_( \
103 "Target bitrate of the transcoded audio stream." )
104 #define ARATE_TEXT N_("Audio sample rate")
105 #define ARATE_LONGTEXT N_( \
106 "Sample rate of the transcoded audio stream (11250, 22500, 44100 or 48000).")
107 #define ACHANS_TEXT N_("Audio channels")
108 #define ACHANS_LONGTEXT N_( \
109 "Number of audio channels in the transcoded streams." )
110 #define AFILTER_TEXT N_("Audio filter")
111 #define AFILTER_LONGTEXT N_( \
112 "Audio filters will be applied to the audio streams (after conversion " \
113 "filters are applied). You must enter a comma-separated list of filters." )
115 #define SENC_TEXT N_("Subtitles encoder")
116 #define SENC_LONGTEXT N_( \
117 "This is the subtitles encoder module that will be used (and its " \
118 "associated options)." )
119 #define SCODEC_TEXT N_("Destination subtitles codec")
120 #define SCODEC_LONGTEXT N_( \
121 "This is the subtitles codec that will be used." )
123 #define SFILTER_TEXT N_("Overlays")
124 #define SFILTER_LONGTEXT N_( \
125 "This allows you to add overlays (also known as \"subpictures\" on the "\
126 "transcoded video stream. The subpictures produced by the filters will "\
127 "be overlayed directly onto the video. You must specify a comma-separated "\
128 "list of subpicture modules" )
130 #define OSD_TEXT N_("OSD menu")
131 #define OSD_LONGTEXT N_(\
132 "Stream the On Screen Display menu (using the osdmenu subpicture module)." )
134 #define THREADS_TEXT N_("Number of threads")
135 #define THREADS_LONGTEXT N_( \
136 "Number of threads used for the transcoding." )
137 #define HP_TEXT N_("High priority")
138 #define HP_LONGTEXT N_( \
139 "Runs the optional encoder thread at the OUTPUT priority instead of " \
142 #define ASYNC_TEXT N_("Synchronise on audio track")
143 #define ASYNC_LONGTEXT N_( \
144 "This option will drop/duplicate video frames to synchronise the video " \
145 "track on the audio track." )
147 #define HURRYUP_TEXT N_( "Hurry up" )
148 #define HURRYUP_LONGTEXT N_( "The transcoder will drop frames if your CPU " \
149 "can't keep up with the encoding rate." )
151 static const char *const ppsz_deinterlace_type[] =
153 "deinterlace", "ffmpeg-deinterlace"
156 static int Open ( vlc_object_t * );
157 static void Close( vlc_object_t * );
159 #define SOUT_CFG_PREFIX "sout-transcode-"
162 set_shortname( N_("Transcode"))
163 set_description( N_("Transcode stream output") )
164 set_capability( "sout stream", 50 )
165 add_shortcut( "transcode" )
166 set_callbacks( Open, Close )
167 set_category( CAT_SOUT )
168 set_subcategory( SUBCAT_SOUT_STREAM )
169 set_section( N_("Video"), NULL )
170 add_module( SOUT_CFG_PREFIX "venc", "encoder", NULL, NULL, VENC_TEXT,
171 VENC_LONGTEXT, false )
172 add_string( SOUT_CFG_PREFIX "vcodec", NULL, NULL, VCODEC_TEXT,
173 VCODEC_LONGTEXT, false )
174 add_integer( SOUT_CFG_PREFIX "vb", 0, NULL, VB_TEXT,
176 add_float( SOUT_CFG_PREFIX "scale", 1, NULL, SCALE_TEXT,
177 SCALE_LONGTEXT, false )
178 add_float( SOUT_CFG_PREFIX "fps", 0, NULL, FPS_TEXT,
179 FPS_LONGTEXT, false )
180 add_bool( SOUT_CFG_PREFIX "hurry-up", true, NULL, HURRYUP_TEXT,
181 HURRYUP_LONGTEXT, false )
182 add_bool( SOUT_CFG_PREFIX "deinterlace", 0, NULL, DEINTERLACE_TEXT,
183 DEINTERLACE_LONGTEXT, false )
184 add_string( SOUT_CFG_PREFIX "deinterlace-module", "deinterlace", NULL,
185 DEINTERLACE_MODULE_TEXT, DEINTERLACE_MODULE_LONGTEXT,
187 change_string_list( ppsz_deinterlace_type, 0, 0 )
188 add_integer( SOUT_CFG_PREFIX "width", 0, NULL, WIDTH_TEXT,
189 WIDTH_LONGTEXT, true )
190 add_integer( SOUT_CFG_PREFIX "height", 0, NULL, HEIGHT_TEXT,
191 HEIGHT_LONGTEXT, true )
192 add_integer( SOUT_CFG_PREFIX "maxwidth", 0, NULL, MAXWIDTH_TEXT,
193 MAXWIDTH_LONGTEXT, true )
194 add_integer( SOUT_CFG_PREFIX "maxheight", 0, NULL, MAXHEIGHT_TEXT,
195 MAXHEIGHT_LONGTEXT, true )
196 add_module_list( SOUT_CFG_PREFIX "vfilter", "video filter2",
198 VFILTER_TEXT, VFILTER_LONGTEXT, false )
200 set_section( N_("Audio"), NULL )
201 add_module( SOUT_CFG_PREFIX "aenc", "encoder", NULL, NULL, AENC_TEXT,
202 AENC_LONGTEXT, false )
203 add_string( SOUT_CFG_PREFIX "acodec", NULL, NULL, ACODEC_TEXT,
204 ACODEC_LONGTEXT, false )
205 add_integer( SOUT_CFG_PREFIX "ab", 0, NULL, AB_TEXT,
207 add_integer( SOUT_CFG_PREFIX "channels", 0, NULL, ACHANS_TEXT,
208 ACHANS_LONGTEXT, false )
209 add_integer( SOUT_CFG_PREFIX "samplerate", 0, NULL, ARATE_TEXT,
210 ARATE_LONGTEXT, true )
211 add_bool( SOUT_CFG_PREFIX "audio-sync", 0, NULL, ASYNC_TEXT,
212 ASYNC_LONGTEXT, false )
213 add_module_list( SOUT_CFG_PREFIX "afilter", "audio filter2",
215 AFILTER_TEXT, AFILTER_LONGTEXT, false )
217 set_section( N_("Overlays/Subtitles"), NULL )
218 add_module( SOUT_CFG_PREFIX "senc", "encoder", NULL, NULL, SENC_TEXT,
219 SENC_LONGTEXT, false )
220 add_string( SOUT_CFG_PREFIX "scodec", NULL, NULL, SCODEC_TEXT,
221 SCODEC_LONGTEXT, false )
222 add_bool( SOUT_CFG_PREFIX "soverlay", 0, NULL, SCODEC_TEXT,
223 SCODEC_LONGTEXT, false )
224 add_module_list( SOUT_CFG_PREFIX "sfilter", "video filter",
226 SFILTER_TEXT, SFILTER_LONGTEXT, false )
228 set_section( N_("On Screen Display"), NULL )
229 add_bool( SOUT_CFG_PREFIX "osd", 0, NULL, OSD_TEXT,
230 OSD_LONGTEXT, false )
232 set_section( N_("Miscellaneous"), NULL )
233 add_integer( SOUT_CFG_PREFIX "threads", 0, NULL, THREADS_TEXT,
234 THREADS_LONGTEXT, true )
235 add_bool( SOUT_CFG_PREFIX "high-priority", 0, NULL, HP_TEXT, HP_LONGTEXT,
240 static const char *const ppsz_sout_options[] = {
241 "venc", "vcodec", "vb",
242 "scale", "fps", "width", "height", "vfilter", "deinterlace",
243 "deinterlace-module", "threads", "hurry-up", "aenc", "acodec", "ab",
244 "afilter", "samplerate", "channels", "senc", "scodec", "soverlay",
245 "sfilter", "osd", "audio-sync", "high-priority", "maxwidth", "maxheight",
249 /*****************************************************************************
250 * Exported prototypes
251 *****************************************************************************/
252 static sout_stream_id_t *Add ( sout_stream_t *, es_format_t * );
253 static int Del ( sout_stream_t *, sout_stream_id_t * );
254 static int Send( sout_stream_t *, sout_stream_id_t *, block_t* );
256 static int transcode_audio_new ( sout_stream_t *, sout_stream_id_t * );
257 static void transcode_audio_close ( sout_stream_id_t * );
258 static int transcode_audio_process( sout_stream_t *, sout_stream_id_t *,
259 block_t *, block_t ** );
261 static aout_buffer_t *audio_new_buffer( decoder_t *, int );
262 static void audio_del_buffer( decoder_t *, aout_buffer_t * );
264 static int transcode_video_new ( sout_stream_t *, sout_stream_id_t * );
265 static void transcode_video_close ( sout_stream_t *, sout_stream_id_t * );
266 static void transcode_video_encoder_init( sout_stream_t *, sout_stream_id_t *);
267 static int transcode_video_encoder_open( sout_stream_t *, sout_stream_id_t *);
268 static int transcode_video_process( sout_stream_t *, sout_stream_id_t *,
269 block_t *, block_t ** );
271 static 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 * );
276 static int transcode_spu_new ( sout_stream_t *, sout_stream_id_t * );
277 static void transcode_spu_close ( sout_stream_id_t * );
278 static int transcode_spu_process( sout_stream_t *, sout_stream_id_t *,
279 block_t *, block_t ** );
281 static int transcode_osd_new ( sout_stream_t *, sout_stream_id_t * );
282 static void transcode_osd_close ( sout_stream_t *, sout_stream_id_t * );
283 static int transcode_osd_process( sout_stream_t *, sout_stream_id_t *,
284 block_t *, block_t ** );
286 static void* EncoderThread( vlc_object_t * p_this );
288 static const int pi_channels_maps[6] =
291 AOUT_CHAN_CENTER, AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
292 AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
293 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
294 | AOUT_CHAN_REARRIGHT,
295 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
296 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
299 #define PICTURE_RING_SIZE 64
300 #define SUBPICTURE_RING_SIZE 20
302 #define ENC_FRAMERATE (25 * 1000 + .5)
303 #define ENC_FRAMERATE_BASE 1000
305 struct sout_stream_sys_t
309 sout_stream_t *p_out;
310 sout_stream_id_t *id_video;
312 vlc_mutex_t lock_out;
314 picture_t * pp_pics[PICTURE_RING_SIZE];
315 int i_first_pic, i_last_pic;
318 vlc_fourcc_t i_acodec; /* codec audio (0 if not transcode) */
320 config_chain_t *p_audio_cfg;
321 uint32_t i_sample_rate;
328 vlc_fourcc_t i_vcodec; /* codec video (0 if not transcode) */
330 config_chain_t *p_video_cfg;
334 unsigned int i_width, i_maxwidth;
335 unsigned int i_height, i_maxheight;
337 char *psz_deinterlace;
338 config_chain_t *p_deinterlace_cfg;
340 bool b_high_priority;
346 vlc_fourcc_t i_scodec; /* codec spu (0 if not transcode) */
349 config_chain_t *p_spu_cfg;
353 vlc_fourcc_t i_osdcodec; /* codec osd menu (0 if not transcode) */
355 config_chain_t *p_osd_cfg;
356 bool b_osd; /* true when osd es is registered */
360 mtime_t i_master_drift;
363 struct decoder_owner_sys_t
365 sout_stream_sys_t *p_sys;
368 /*****************************************************************************
370 *****************************************************************************/
371 static int Open( vlc_object_t *p_this )
373 sout_stream_t *p_stream = (sout_stream_t*)p_this;
374 sout_stream_sys_t *p_sys;
377 p_sys = vlc_object_create( p_this, sizeof( sout_stream_sys_t ) );
379 p_sys->p_out = sout_StreamNew( p_stream->p_sout, p_stream->psz_next );
382 msg_Err( p_stream, "cannot create chain" );
383 vlc_object_release( p_sys );
387 p_sys->i_master_drift = 0;
389 config_ChainParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options,
392 /* Audio transcoding parameters */
393 var_Get( p_stream, SOUT_CFG_PREFIX "aenc", &val );
394 p_sys->psz_aenc = NULL;
395 p_sys->p_audio_cfg = NULL;
396 if( val.psz_string && *val.psz_string )
399 psz_next = config_ChainCreate( &p_sys->psz_aenc, &p_sys->p_audio_cfg,
403 free( val.psz_string );
405 var_Get( p_stream, SOUT_CFG_PREFIX "acodec", &val );
407 if( val.psz_string && *val.psz_string )
410 memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) );
411 p_sys->i_acodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
413 free( val.psz_string );
415 var_Get( p_stream, SOUT_CFG_PREFIX "ab", &val );
416 p_sys->i_abitrate = val.i_int;
417 if( p_sys->i_abitrate < 4000 ) p_sys->i_abitrate *= 1000;
419 var_Get( p_stream, SOUT_CFG_PREFIX "samplerate", &val );
420 p_sys->i_sample_rate = val.i_int;
422 var_Get( p_stream, SOUT_CFG_PREFIX "channels", &val );
423 p_sys->i_channels = val.i_int;
425 if( p_sys->i_acodec )
427 if( ( p_sys->i_acodec == VLC_CODEC_MP3 ||
428 p_sys->i_acodec == VLC_CODEC_MPGA ) && p_sys->i_channels > 2 )
430 msg_Warn( p_stream, "%d channels invalid for mp3, forcing to 2",
432 p_sys->i_channels = 2;
434 msg_Dbg( p_stream, "codec audio=%4.4s %dHz %d channels %dKb/s",
435 (char *)&p_sys->i_acodec, p_sys->i_sample_rate,
436 p_sys->i_channels, p_sys->i_abitrate / 1000 );
439 var_Get( p_stream, SOUT_CFG_PREFIX "afilter", &val );
440 if( val.psz_string && *val.psz_string )
441 p_sys->psz_af2 = val.psz_string;
444 free( val.psz_string );
445 p_sys->psz_af2 = NULL;
448 /* Video transcoding parameters */
449 var_Get( p_stream, SOUT_CFG_PREFIX "venc", &val );
450 p_sys->psz_venc = NULL;
451 p_sys->p_video_cfg = NULL;
452 if( val.psz_string && *val.psz_string )
455 psz_next = config_ChainCreate( &p_sys->psz_venc, &p_sys->p_video_cfg,
459 free( val.psz_string );
461 var_Get( p_stream, SOUT_CFG_PREFIX "vcodec", &val );
463 if( val.psz_string && *val.psz_string )
466 memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) );
467 p_sys->i_vcodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
469 free( val.psz_string );
471 var_Get( p_stream, SOUT_CFG_PREFIX "vb", &val );
472 p_sys->i_vbitrate = val.i_int;
473 if( p_sys->i_vbitrate < 16000 ) p_sys->i_vbitrate *= 1000;
475 var_Get( p_stream, SOUT_CFG_PREFIX "scale", &val );
476 p_sys->f_scale = val.f_float;
478 var_Get( p_stream, SOUT_CFG_PREFIX "fps", &val );
479 p_sys->f_fps = val.f_float;
481 var_Get( p_stream, SOUT_CFG_PREFIX "hurry-up", &val );
482 p_sys->b_hurry_up = val.b_bool;
484 var_Get( p_stream, SOUT_CFG_PREFIX "width", &val );
485 p_sys->i_width = val.i_int;
487 var_Get( p_stream, SOUT_CFG_PREFIX "height", &val );
488 p_sys->i_height = val.i_int;
490 var_Get( p_stream, SOUT_CFG_PREFIX "maxwidth", &val );
491 p_sys->i_maxwidth = val.i_int;
493 var_Get( p_stream, SOUT_CFG_PREFIX "maxheight", &val );
494 p_sys->i_maxheight = val.i_int;
496 var_Get( p_stream, SOUT_CFG_PREFIX "vfilter", &val );
497 if( val.psz_string && *val.psz_string )
498 p_sys->psz_vf2 = val.psz_string;
501 free( val.psz_string );
502 p_sys->psz_vf2 = NULL;
505 var_Get( p_stream, SOUT_CFG_PREFIX "deinterlace", &val );
506 p_sys->b_deinterlace = val.b_bool;
508 var_Get( p_stream, SOUT_CFG_PREFIX "deinterlace-module", &val );
509 p_sys->psz_deinterlace = NULL;
510 p_sys->p_deinterlace_cfg = NULL;
511 if( val.psz_string && *val.psz_string )
514 psz_next = config_ChainCreate( &p_sys->psz_deinterlace,
515 &p_sys->p_deinterlace_cfg,
519 free( val.psz_string );
521 var_Get( p_stream, SOUT_CFG_PREFIX "threads", &val );
522 p_sys->i_threads = val.i_int;
523 var_Get( p_stream, SOUT_CFG_PREFIX "high-priority", &val );
524 p_sys->b_high_priority = val.b_bool;
526 if( p_sys->i_vcodec )
528 msg_Dbg( p_stream, "codec video=%4.4s %dx%d scaling: %f %dkb/s",
529 (char *)&p_sys->i_vcodec, p_sys->i_width, p_sys->i_height,
530 p_sys->f_scale, p_sys->i_vbitrate / 1000 );
533 /* Subpictures transcoding parameters */
535 p_sys->psz_senc = NULL;
536 p_sys->p_spu_cfg = NULL;
539 var_Get( p_stream, SOUT_CFG_PREFIX "senc", &val );
540 if( val.psz_string && *val.psz_string )
543 psz_next = config_ChainCreate( &p_sys->psz_senc, &p_sys->p_spu_cfg,
547 free( val.psz_string );
549 var_Get( p_stream, SOUT_CFG_PREFIX "scodec", &val );
550 if( val.psz_string && *val.psz_string )
553 memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) );
554 p_sys->i_scodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] );
556 free( val.psz_string );
558 if( p_sys->i_scodec )
560 msg_Dbg( p_stream, "codec spu=%4.4s", (char *)&p_sys->i_scodec );
563 var_Get( p_stream, SOUT_CFG_PREFIX "soverlay", &val );
564 p_sys->b_soverlay = val.b_bool;
566 var_Get( p_stream, SOUT_CFG_PREFIX "sfilter", &val );
567 if( val.psz_string && *val.psz_string )
569 p_sys->p_spu = spu_Create( p_stream );
570 var_Create( p_sys->p_spu, "sub-filter", VLC_VAR_STRING );
571 var_Set( p_sys->p_spu, "sub-filter", val );
572 spu_Init( p_sys->p_spu );
574 free( val.psz_string );
576 /* OSD menu transcoding parameters */
577 p_sys->psz_osdenc = NULL;
578 p_sys->p_osd_cfg = NULL;
579 p_sys->i_osdcodec = 0;
580 p_sys->b_osd = false;
582 var_Get( p_stream, SOUT_CFG_PREFIX "osd", &val );
588 psz_next = config_ChainCreate( &p_sys->psz_osdenc,
589 &p_sys->p_osd_cfg, strdup( "dvbsub") );
592 p_sys->i_osdcodec = VLC_CODEC_YUVP;
594 msg_Dbg( p_stream, "codec osd=%4.4s", (char *)&p_sys->i_osdcodec );
598 osd_val.psz_string = strdup("osdmenu");
599 p_sys->p_spu = spu_Create( p_stream );
600 var_Create( p_sys->p_spu, "sub-filter", VLC_VAR_STRING );
601 var_Set( p_sys->p_spu, "sub-filter", osd_val );
602 spu_Init( p_sys->p_spu );
603 free( osd_val.psz_string );
607 osd_val.psz_string = strdup("osdmenu");
608 var_Set( p_sys->p_spu, "sub-filter", osd_val );
609 free( osd_val.psz_string );
614 var_Get( p_stream, SOUT_CFG_PREFIX "audio-sync", &val );
615 p_sys->b_master_sync = val.b_bool;
616 if( p_sys->f_fps > 0 ) p_sys->b_master_sync = true;
618 p_stream->pf_add = Add;
619 p_stream->pf_del = Del;
620 p_stream->pf_send = Send;
621 p_stream->p_sys = p_sys;
626 /*****************************************************************************
628 *****************************************************************************/
629 static void Close( vlc_object_t * p_this )
631 sout_stream_t *p_stream = (sout_stream_t*)p_this;
632 sout_stream_sys_t *p_sys = p_stream->p_sys;
634 sout_StreamDelete( p_sys->p_out );
636 free( p_sys->psz_af2 );
638 config_ChainDestroy( p_sys->p_audio_cfg );
639 free( p_sys->psz_aenc );
641 free( p_sys->psz_vf2 );
643 config_ChainDestroy( p_sys->p_video_cfg );
644 free( p_sys->psz_venc );
646 config_ChainDestroy( p_sys->p_deinterlace_cfg );
647 free( p_sys->psz_deinterlace );
649 config_ChainDestroy( p_sys->p_spu_cfg );
650 free( p_sys->psz_senc );
652 if( p_sys->p_spu ) spu_Destroy( p_sys->p_spu );
654 config_ChainDestroy( p_sys->p_osd_cfg );
655 free( p_sys->psz_osdenc );
657 vlc_object_release( p_sys );
660 struct sout_stream_id_t
664 /* id of the out stream */
668 decoder_t *p_decoder;
671 filter_chain_t *p_f_chain;
672 /* User specified filters */
673 filter_chain_t *p_uf_chain;
676 encoder_t *p_encoder;
679 date_t interpolated_pts;
682 static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
684 sout_stream_sys_t *p_sys = p_stream->p_sys;
685 sout_stream_id_t *id;
687 id = calloc( 1, sizeof( sout_stream_id_t ) );
692 id->p_decoder = NULL;
693 id->p_encoder = NULL;
695 /* Create decoder object */
696 id->p_decoder = vlc_object_create( p_stream, VLC_OBJECT_DECODER );
699 vlc_object_attach( id->p_decoder, p_stream );
700 id->p_decoder->p_module = NULL;
701 id->p_decoder->fmt_in = *p_fmt;
702 id->p_decoder->b_pace_control = true;
704 /* Create encoder object */
705 id->p_encoder = sout_EncoderCreate( p_stream );
708 vlc_object_attach( id->p_encoder, p_stream );
709 id->p_encoder->p_module = NULL;
711 /* Create destination format */
712 es_format_Init( &id->p_encoder->fmt_out, p_fmt->i_cat, 0 );
713 id->p_encoder->fmt_out.i_id = p_fmt->i_id;
714 id->p_encoder->fmt_out.i_group = p_fmt->i_group;
715 if( p_fmt->psz_language )
716 id->p_encoder->fmt_out.psz_language = strdup( p_fmt->psz_language );
718 if( p_fmt->i_cat == AUDIO_ES && (p_sys->i_acodec || p_sys->psz_aenc) )
721 "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
722 (char*)&p_fmt->i_codec, (char*)&p_sys->i_acodec );
724 /* Complete destination format */
725 id->p_encoder->fmt_out.i_codec = p_sys->i_acodec;
726 id->p_encoder->fmt_out.audio.i_rate = p_sys->i_sample_rate > 0 ?
727 p_sys->i_sample_rate : p_fmt->audio.i_rate;
728 id->p_encoder->fmt_out.i_bitrate = p_sys->i_abitrate;
729 id->p_encoder->fmt_out.audio.i_bitspersample =
730 p_fmt->audio.i_bitspersample;
731 id->p_encoder->fmt_out.audio.i_channels = p_sys->i_channels > 0 ?
732 p_sys->i_channels : p_fmt->audio.i_channels;
733 /* Sanity check for audio channels */
734 id->p_encoder->fmt_out.audio.i_channels =
735 __MIN( id->p_encoder->fmt_out.audio.i_channels,
736 id->p_decoder->fmt_in.audio.i_channels );
737 id->p_encoder->fmt_out.audio.i_original_channels =
738 id->p_decoder->fmt_in.audio.i_physical_channels;
739 if( id->p_decoder->fmt_in.audio.i_channels ==
740 id->p_encoder->fmt_out.audio.i_channels )
742 id->p_encoder->fmt_out.audio.i_physical_channels =
743 id->p_decoder->fmt_in.audio.i_physical_channels;
747 id->p_encoder->fmt_out.audio.i_physical_channels =
748 pi_channels_maps[id->p_encoder->fmt_out.audio.i_channels];
751 /* Build decoder -> filter -> encoder chain */
752 if( transcode_audio_new( p_stream, id ) )
754 msg_Err( p_stream, "cannot create audio chain" );
758 /* Open output stream */
759 id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_encoder->fmt_out );
760 id->b_transcode = true;
764 transcode_audio_close( id );
768 date_Init( &id->interpolated_pts, p_fmt->audio.i_rate, 1 );
770 else if( p_fmt->i_cat == VIDEO_ES &&
771 (p_sys->i_vcodec != 0 || p_sys->psz_venc) )
774 "creating video transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
775 (char*)&p_fmt->i_codec, (char*)&p_sys->i_vcodec );
777 /* Complete destination format */
778 id->p_encoder->fmt_out.i_codec = p_sys->i_vcodec;
779 id->p_encoder->fmt_out.video.i_width = p_sys->i_width & ~1;
780 id->p_encoder->fmt_out.video.i_height = p_sys->i_height & ~1;
781 id->p_encoder->fmt_out.i_bitrate = p_sys->i_vbitrate;
783 /* Build decoder -> filter -> encoder chain */
784 if( transcode_video_new( p_stream, id ) )
786 msg_Err( p_stream, "cannot create video chain" );
790 /* Stream will be added later on because we don't know
791 * all the characteristics of the decoded stream yet */
792 id->b_transcode = true;
794 if( p_sys->f_fps > 0 )
796 id->p_encoder->fmt_out.video.i_frame_rate =
797 (p_sys->f_fps * 1000) + 0.5;
798 id->p_encoder->fmt_out.video.i_frame_rate_base =
802 else if( ( p_fmt->i_cat == SPU_ES ) &&
803 ( p_sys->i_scodec || p_sys->psz_senc ) )
805 msg_Dbg( p_stream, "creating subtitles transcoding from fcc=`%4.4s' "
806 "to fcc=`%4.4s'", (char*)&p_fmt->i_codec,
807 (char*)&p_sys->i_scodec );
809 /* Complete destination format */
810 id->p_encoder->fmt_out.i_codec = p_sys->i_scodec;
812 /* build decoder -> filter -> encoder */
813 if( transcode_spu_new( p_stream, id ) )
815 msg_Err( p_stream, "cannot create subtitles chain" );
819 /* open output stream */
820 id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_encoder->fmt_out );
821 id->b_transcode = true;
825 transcode_spu_close( id );
829 else if( p_fmt->i_cat == SPU_ES && p_sys->b_soverlay )
831 msg_Dbg( p_stream, "subtitles (fcc=`%4.4s') overlaying",
832 (char*)&p_fmt->i_codec );
834 id->b_transcode = true;
836 /* Build decoder -> filter -> overlaying chain */
837 if( transcode_spu_new( p_stream, id ) )
839 msg_Err( p_stream, "cannot create subtitles chain" );
843 else if( !p_sys->b_osd && (p_sys->i_osdcodec != 0 || p_sys->psz_osdenc) )
845 msg_Dbg( p_stream, "creating osd transcoding from fcc=`%4.4s' "
846 "to fcc=`%4.4s'", (char*)&p_fmt->i_codec,
847 (char*)&p_sys->i_scodec );
849 id->b_transcode = true;
851 /* Create a fake OSD menu elementary stream */
852 if( transcode_osd_new( p_stream, id ) )
854 msg_Err( p_stream, "cannot create osd chain" );
861 msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
862 (char*)&p_fmt->i_codec );
863 id->id = sout_StreamIdAdd( p_sys->p_out, p_fmt );
864 id->b_transcode = false;
866 if( !id->id ) goto error;
876 vlc_object_detach( id->p_decoder );
877 vlc_object_release( id->p_decoder );
878 id->p_decoder = NULL;
883 vlc_object_detach( id->p_encoder );
884 es_format_Clean( &id->p_encoder->fmt_out );
885 vlc_object_release( id->p_encoder );
886 id->p_encoder = NULL;
894 static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
896 sout_stream_sys_t *p_sys = p_stream->p_sys;
898 if( id->b_transcode )
900 switch( id->p_decoder->fmt_in.i_cat )
903 transcode_audio_close( id );
906 transcode_video_close( p_stream, id );
910 transcode_osd_close( p_stream, id );
912 transcode_spu_close( id );
917 if( id->id ) sout_StreamIdDel( p_sys->p_out, id->id );
921 vlc_object_detach( id->p_decoder );
922 vlc_object_release( id->p_decoder );
923 id->p_decoder = NULL;
928 vlc_object_detach( id->p_encoder );
929 es_format_Clean( &id->p_encoder->fmt_out );
930 vlc_object_release( id->p_encoder );
931 id->p_encoder = NULL;
938 static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
941 sout_stream_sys_t *p_sys = p_stream->p_sys;
942 block_t *p_out = NULL;
944 if( !id->b_transcode )
947 return sout_StreamIdSend( p_sys->p_out, id->id, p_buffer );
949 block_Release( p_buffer );
953 switch( id->p_decoder->fmt_in.i_cat )
956 transcode_audio_process( p_stream, id, p_buffer, &p_out );
960 if( transcode_video_process( p_stream, id, p_buffer, &p_out )
968 /* Transcode OSD menu pictures. */
971 if( transcode_osd_process( p_stream, id, p_buffer, &p_out ) !=
977 else if ( transcode_spu_process( p_stream, id, p_buffer, &p_out ) !=
986 block_Release( p_buffer );
991 return sout_StreamIdSend( p_sys->p_out, id->id, p_out );
995 /****************************************************************************
997 ****************************************************************************/
998 static inline void video_timer_start( encoder_t * p_encoder )
1000 stats_TimerStart( p_encoder, "encoding video frame",
1001 STATS_TIMER_VIDEO_FRAME_ENCODING );
1004 static inline void video_timer_stop( encoder_t * p_encoder )
1006 stats_TimerStop( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1009 static inline void video_timer_close( encoder_t * p_encoder )
1011 stats_TimerDump( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1012 stats_TimerClean( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );
1015 static inline void audio_timer_start( encoder_t * p_encoder )
1017 stats_TimerStart( p_encoder, "encoding audio frame",
1018 STATS_TIMER_AUDIO_FRAME_ENCODING );
1021 static inline void audio_timer_stop( encoder_t * p_encoder )
1023 stats_TimerStop( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1026 static inline void audio_timer_close( encoder_t * p_encoder )
1028 stats_TimerDump( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1029 stats_TimerClean( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );
1032 /****************************************************************************
1033 * decoder reencoder part
1034 ****************************************************************************/
1036 static block_t *transcode_audio_alloc( filter_t *p_filter, int size )
1038 VLC_UNUSED( p_filter );
1039 return block_Alloc( size );
1042 static int transcode_audio_filter_allocation_init( filter_t *p_filter,
1046 p_filter->pf_audio_buffer_new = transcode_audio_alloc;
1050 static bool transcode_audio_filter_needed( const es_format_t *p_fmt1, const es_format_t *p_fmt2 )
1052 if( p_fmt1->i_codec != p_fmt2->i_codec ||
1053 p_fmt1->audio.i_channels != p_fmt2->audio.i_channels ||
1054 p_fmt1->audio.i_rate != p_fmt2->audio.i_rate )
1058 static int transcode_audio_filter_chain_build( sout_stream_t *p_stream, filter_chain_t *p_chain,
1059 const es_format_t *p_dst, const es_format_t *p_src )
1061 if( !transcode_audio_filter_needed( p_dst, p_src ) )
1064 es_format_t current = *p_src;
1066 msg_Dbg( p_stream, "Looking for filter "
1067 "(%4.4s->%4.4s, channels %d->%d, rate %d->%d)",
1068 (const char *)&p_src->i_codec,
1069 (const char *)&p_dst->i_codec,
1070 p_src->audio.i_channels,
1071 p_dst->audio.i_channels,
1072 p_src->audio.i_rate,
1073 p_dst->audio.i_rate );
1075 /* If any filter is needed, convert to fl32 */
1076 if( current.i_codec != VLC_CODEC_FL32 )
1078 /* First step, convert to fl32 */
1080 current.audio.i_format = VLC_CODEC_FL32;
1082 if( !filter_chain_AppendFilter( p_chain, NULL, NULL, NULL, ¤t ) )
1084 msg_Err( p_stream, "Failed to find conversion filter to fl32" );
1085 return VLC_EGENERIC;
1087 current = *filter_chain_GetFmtOut( p_chain );
1090 /* Fix sample rate */
1091 if( current.audio.i_rate != p_dst->audio.i_rate )
1093 current.audio.i_rate = p_dst->audio.i_rate;
1094 if( !filter_chain_AppendFilter( p_chain, NULL, NULL, NULL, ¤t ) )
1096 msg_Err( p_stream, "Failed to find conversion filter for resampling" );
1097 return VLC_EGENERIC;
1099 current = *filter_chain_GetFmtOut( p_chain );
1103 if( current.audio.i_channels != p_dst->audio.i_channels )
1105 current.audio.i_channels = p_dst->audio.i_channels;
1106 current.audio.i_physical_channels = p_dst->audio.i_physical_channels;
1107 current.audio.i_original_channels = p_dst->audio.i_original_channels;
1109 if( ( !current.audio.i_physical_channels || !current.audio.i_original_channels ) &&
1110 current.audio.i_channels < 6 )
1111 current.audio.i_physical_channels =
1112 current.audio.i_original_channels = pi_channels_maps[current.audio.i_channels];
1114 if( !filter_chain_AppendFilter( p_chain, NULL, NULL, NULL, ¤t ) )
1116 msg_Err( p_stream, "Failed to find conversion filter for channel mixing" );
1117 return VLC_EGENERIC;
1119 current = *filter_chain_GetFmtOut( p_chain );
1122 /* And last step, convert to the requested codec */
1123 if( current.i_codec != p_dst->i_codec )
1125 current.i_codec = p_dst->i_codec;
1126 if( !filter_chain_AppendFilter( p_chain, NULL, NULL, NULL, ¤t ) )
1128 msg_Err( p_stream, "Failed to find conversion filter to %4.4s",
1129 (const char*)&p_dst->i_codec);
1130 return VLC_EGENERIC;
1132 current = *filter_chain_GetFmtOut( p_chain );
1135 if( transcode_audio_filter_needed( p_dst, ¤t ) )
1137 /* Weird case, a filter has side effects, doomed */
1138 msg_Err( p_stream, "Failed to create a valid audio filter chain" );
1139 return VLC_EGENERIC;
1142 msg_Dbg( p_stream, "Got complete audio filter chain" );
1146 static int transcode_audio_new( sout_stream_t *p_stream,
1147 sout_stream_id_t *id )
1149 sout_stream_sys_t *p_sys = p_stream->p_sys;
1150 es_format_t fmt_last;
1156 /* Initialization of decoder structures */
1157 id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1158 id->p_decoder->fmt_out.i_extra = 0;
1159 id->p_decoder->fmt_out.p_extra = 0;
1160 id->p_decoder->pf_decode_audio = NULL;
1161 id->p_decoder->pf_aout_buffer_new = audio_new_buffer;
1162 id->p_decoder->pf_aout_buffer_del = audio_del_buffer;
1163 /* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */
1165 id->p_decoder->p_module =
1166 module_need( id->p_decoder, "decoder", "$codec", false );
1167 if( !id->p_decoder->p_module )
1169 msg_Err( p_stream, "cannot find audio decoder" );
1170 return VLC_EGENERIC;
1172 id->p_decoder->fmt_out.audio.i_bitspersample =
1173 aout_BitsPerSample( id->p_decoder->fmt_out.i_codec );
1174 fmt_last = id->p_decoder->fmt_out;
1175 /* Fix AAC SBR changing number of channels and sampling rate */
1176 if( !(id->p_decoder->fmt_in.i_codec == VLC_CODEC_MP4A &&
1177 fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate &&
1178 fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels) )
1179 fmt_last.audio.i_rate = id->p_decoder->fmt_in.audio.i_rate;
1185 /* Initialization of encoder format structures */
1186 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1187 id->p_decoder->fmt_out.i_codec );
1188 id->p_encoder->fmt_in.audio.i_format = id->p_decoder->fmt_out.i_codec;
1190 id->p_encoder->fmt_in.audio.i_rate = id->p_encoder->fmt_out.audio.i_rate;
1191 id->p_encoder->fmt_in.audio.i_physical_channels =
1192 id->p_encoder->fmt_out.audio.i_physical_channels;
1193 id->p_encoder->fmt_in.audio.i_original_channels =
1194 id->p_encoder->fmt_out.audio.i_original_channels;
1195 id->p_encoder->fmt_in.audio.i_channels =
1196 id->p_encoder->fmt_out.audio.i_channels;
1197 id->p_encoder->fmt_in.audio.i_bitspersample =
1198 aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1200 id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
1201 id->p_encoder->p_module =
1202 module_need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
1203 if( !id->p_encoder->p_module )
1205 msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)",
1206 p_sys->psz_aenc ? p_sys->psz_aenc : "any",
1207 (char *)&p_sys->i_acodec );
1208 module_unneed( id->p_decoder, id->p_decoder->p_module );
1209 id->p_decoder->p_module = NULL;
1210 return VLC_EGENERIC;
1212 id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
1213 id->p_encoder->fmt_in.audio.i_bitspersample =
1214 aout_BitsPerSample( id->p_encoder->fmt_in.i_codec );
1216 /* Load user specified audio filters */
1217 if( p_sys->psz_af2 )
1219 es_format_t fmt_fl32 = fmt_last;
1221 fmt_fl32.audio.i_format = VLC_CODEC_FL32;
1222 if( transcode_audio_filter_chain_build( p_stream, id->p_uf_chain,
1223 &fmt_fl32, &fmt_last ) )
1225 transcode_audio_close( id );
1226 return VLC_EGENERIC;
1228 fmt_last = fmt_fl32;
1230 id->p_uf_chain = filter_chain_New( p_stream, "audio filter2", false,
1231 transcode_audio_filter_allocation_init, NULL, NULL );
1232 filter_chain_Reset( id->p_uf_chain, &fmt_last, &fmt_fl32 );
1233 if( filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_af2 ) > 0 )
1234 fmt_last = *filter_chain_GetFmtOut( id->p_uf_chain );
1237 /* Load conversion filters */
1238 id->p_f_chain = filter_chain_New( p_stream, "audio filter2", true,
1239 transcode_audio_filter_allocation_init, NULL, NULL );
1240 filter_chain_Reset( id->p_f_chain, &fmt_last, &id->p_encoder->fmt_in );
1242 if( transcode_audio_filter_chain_build( p_stream, id->p_f_chain,
1243 &id->p_encoder->fmt_in, &fmt_last ) )
1245 transcode_audio_close( id );
1246 return VLC_EGENERIC;
1248 fmt_last = id->p_encoder->fmt_in;
1251 id->p_encoder->fmt_out.i_codec =
1252 vlc_fourcc_GetCodec( AUDIO_ES, id->p_encoder->fmt_out.i_codec );
1257 static void transcode_audio_close( sout_stream_id_t *id )
1259 audio_timer_close( id->p_encoder );
1262 if( id->p_decoder->p_module )
1263 module_unneed( id->p_decoder, id->p_decoder->p_module );
1264 id->p_decoder->p_module = NULL;
1266 if( id->p_decoder->p_description )
1267 vlc_meta_Delete( id->p_decoder->p_description );
1268 id->p_decoder->p_description = NULL;
1271 if( id->p_encoder->p_module )
1272 module_unneed( id->p_encoder, id->p_encoder->p_module );
1273 id->p_encoder->p_module = NULL;
1276 if( id->p_uf_chain )
1277 filter_chain_Delete( id->p_uf_chain );
1279 filter_chain_Delete( id->p_f_chain );
1282 static int transcode_audio_process( sout_stream_t *p_stream,
1283 sout_stream_id_t *id,
1284 block_t *in, block_t **out )
1286 sout_stream_sys_t *p_sys = p_stream->p_sys;
1287 aout_buffer_t *p_audio_buf;
1288 block_t *p_block, *p_audio_block;
1291 while( (p_audio_buf = id->p_decoder->pf_decode_audio( id->p_decoder,
1294 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_AUDIO, 1 );
1295 if( p_sys->b_master_sync )
1297 mtime_t i_dts = date_Get( &id->interpolated_pts ) + 1;
1298 if ( p_audio_buf->start_date - i_dts > MASTER_SYNC_MAX_DRIFT
1299 || p_audio_buf->start_date - i_dts < -MASTER_SYNC_MAX_DRIFT )
1301 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1302 date_Set( &id->interpolated_pts, p_audio_buf->start_date );
1303 i_dts = p_audio_buf->start_date + 1;
1305 p_sys->i_master_drift = p_audio_buf->start_date - i_dts;
1306 date_Increment( &id->interpolated_pts, p_audio_buf->i_nb_samples );
1307 p_audio_buf->start_date -= p_sys->i_master_drift;
1308 p_audio_buf->end_date -= p_sys->i_master_drift;
1311 p_audio_block = p_audio_buf->p_sys;
1312 p_audio_block->i_buffer = p_audio_buf->i_nb_bytes;
1313 p_audio_block->i_dts = p_audio_block->i_pts =
1314 p_audio_buf->start_date;
1315 p_audio_block->i_length = p_audio_buf->end_date -
1316 p_audio_buf->start_date;
1317 p_audio_block->i_samples = p_audio_buf->i_nb_samples;
1319 /* Run filter chain */
1320 if( id->p_uf_chain )
1322 p_audio_block = filter_chain_AudioFilter( id->p_uf_chain, p_audio_block );
1323 assert( p_audio_block );
1326 p_audio_block = filter_chain_AudioFilter( id->p_f_chain, p_audio_block );
1327 assert( p_audio_block );
1329 p_audio_buf->p_buffer = p_audio_block->p_buffer;
1330 p_audio_buf->i_nb_bytes = p_audio_block->i_buffer;
1331 p_audio_buf->i_nb_samples = p_audio_block->i_samples;
1332 p_audio_buf->start_date = p_audio_block->i_dts;
1333 p_audio_buf->end_date = p_audio_block->i_dts + p_audio_block->i_length;
1335 audio_timer_start( id->p_encoder );
1336 p_block = id->p_encoder->pf_encode_audio( id->p_encoder, p_audio_buf );
1337 audio_timer_stop( id->p_encoder );
1339 block_ChainAppend( out, p_block );
1340 block_Release( p_audio_block );
1341 free( p_audio_buf );
1347 static void audio_release_buffer( aout_buffer_t *p_buffer )
1349 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1353 static aout_buffer_t *audio_new_buffer( decoder_t *p_dec, int i_samples )
1355 aout_buffer_t *p_buffer;
1359 if( p_dec->fmt_out.audio.i_bitspersample )
1361 i_size = i_samples * p_dec->fmt_out.audio.i_bitspersample / 8 *
1362 p_dec->fmt_out.audio.i_channels;
1364 else if( p_dec->fmt_out.audio.i_bytes_per_frame &&
1365 p_dec->fmt_out.audio.i_frame_length )
1367 i_size = i_samples * p_dec->fmt_out.audio.i_bytes_per_frame /
1368 p_dec->fmt_out.audio.i_frame_length;
1372 i_size = i_samples * 4 * p_dec->fmt_out.audio.i_channels;
1375 p_buffer = malloc( sizeof(aout_buffer_t) );
1376 if( !p_buffer ) return NULL;
1377 p_buffer->b_discontinuity = false;
1378 p_buffer->pf_release = audio_release_buffer;
1379 p_buffer->p_sys = p_block = block_New( p_dec, i_size );
1381 p_buffer->p_buffer = p_block->p_buffer;
1382 p_buffer->i_size = p_buffer->i_nb_bytes = p_block->i_buffer;
1383 p_buffer->i_nb_samples = i_samples;
1384 p_block->i_samples = i_samples;
1389 static void audio_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
1392 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1400 static picture_t *transcode_video_filter_buffer_new( filter_t *p_filter )
1402 p_filter->fmt_out.video.i_chroma = p_filter->fmt_out.i_codec;
1403 return picture_New( p_filter->fmt_out.video.i_chroma,
1404 p_filter->fmt_out.video.i_width,
1405 p_filter->fmt_out.video.i_height,
1406 p_filter->fmt_out.video.i_aspect );
1408 static void transcode_video_filter_buffer_del( filter_t *p_filter, picture_t *p_pic )
1410 VLC_UNUSED(p_filter);
1411 picture_Release( p_pic );
1414 static int transcode_video_filter_allocation_init( filter_t *p_filter,
1418 p_filter->pf_vout_buffer_new = transcode_video_filter_buffer_new;
1419 p_filter->pf_vout_buffer_del = transcode_video_filter_buffer_del;
1423 static void transcode_video_filter_allocation_clear( filter_t *p_filter )
1425 VLC_UNUSED(p_filter);
1428 static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
1430 sout_stream_sys_t *p_sys = p_stream->p_sys;
1433 * Initialization of decoder structures
1435 id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1436 id->p_decoder->fmt_out.i_extra = 0;
1437 id->p_decoder->fmt_out.p_extra = 0;
1438 id->p_decoder->pf_decode_video = NULL;
1439 id->p_decoder->pf_get_cc = NULL;
1440 id->p_decoder->pf_get_cc = 0;
1441 id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
1442 id->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder;
1443 id->p_decoder->pf_picture_link = video_link_picture_decoder;
1444 id->p_decoder->pf_picture_unlink = video_unlink_picture_decoder;
1445 id->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) );
1446 if( !id->p_decoder->p_owner )
1447 return VLC_EGENERIC;
1449 id->p_decoder->p_owner->p_sys = p_sys;
1450 /* id->p_decoder->p_cfg = p_sys->p_video_cfg; */
1452 id->p_decoder->p_module =
1453 module_need( id->p_decoder, "decoder", "$codec", false );
1455 if( !id->p_decoder->p_module )
1457 msg_Err( p_stream, "cannot find video decoder" );
1458 free( id->p_decoder->p_owner );
1459 return VLC_EGENERIC;
1464 * Because some info about the decoded input will only be available
1465 * once the first frame is decoded, we actually only test the availability
1466 * of the encoder here.
1469 /* Initialization of encoder format structures */
1470 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1471 id->p_decoder->fmt_out.i_codec );
1472 id->p_encoder->fmt_in.video.i_chroma = id->p_decoder->fmt_out.i_codec;
1474 /* The dimensions will be set properly later on.
1475 * Just put sensible values so we can test an encoder is available. */
1476 id->p_encoder->fmt_in.video.i_width =
1477 id->p_encoder->fmt_out.video.i_width
1478 ? id->p_encoder->fmt_out.video.i_width
1479 : id->p_decoder->fmt_in.video.i_width
1480 ? id->p_decoder->fmt_in.video.i_width : 16;
1481 id->p_encoder->fmt_in.video.i_height =
1482 id->p_encoder->fmt_out.video.i_height
1483 ? id->p_encoder->fmt_out.video.i_height
1484 : id->p_decoder->fmt_in.video.i_height
1485 ? id->p_decoder->fmt_in.video.i_height : 16;
1486 id->p_encoder->fmt_in.video.i_frame_rate = ENC_FRAMERATE;
1487 id->p_encoder->fmt_in.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1489 id->p_encoder->i_threads = p_sys->i_threads;
1490 id->p_encoder->p_cfg = p_sys->p_video_cfg;
1492 id->p_encoder->p_module =
1493 module_need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1494 if( !id->p_encoder->p_module )
1496 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1497 p_sys->psz_venc ? p_sys->psz_venc : "any",
1498 (char *)&p_sys->i_vcodec );
1499 module_unneed( id->p_decoder, id->p_decoder->p_module );
1500 id->p_decoder->p_module = 0;
1501 free( id->p_decoder->p_owner );
1502 return VLC_EGENERIC;
1505 /* Close the encoder.
1506 * We'll open it only when we have the first frame. */
1507 module_unneed( id->p_encoder, id->p_encoder->p_module );
1508 if( id->p_encoder->fmt_out.p_extra )
1510 free( id->p_encoder->fmt_out.p_extra );
1511 id->p_encoder->fmt_out.p_extra = NULL;
1512 id->p_encoder->fmt_out.i_extra = 0;
1514 id->p_encoder->p_module = NULL;
1516 if( p_sys->i_threads >= 1 )
1518 int i_priority = p_sys->b_high_priority ? VLC_THREAD_PRIORITY_OUTPUT :
1519 VLC_THREAD_PRIORITY_VIDEO;
1520 p_sys->id_video = id;
1521 vlc_mutex_init( &p_sys->lock_out );
1522 vlc_cond_init( &p_sys->cond );
1523 memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) );
1524 p_sys->i_first_pic = 0;
1525 p_sys->i_last_pic = 0;
1526 p_sys->p_buffers = NULL;
1527 p_sys->b_die = p_sys->b_error = 0;
1528 if( vlc_thread_create( p_sys, "encoder", EncoderThread, i_priority ) )
1530 msg_Err( p_stream, "cannot spawn encoder thread" );
1531 module_unneed( id->p_decoder, id->p_decoder->p_module );
1532 id->p_decoder->p_module = 0;
1533 free( id->p_decoder->p_owner );
1534 return VLC_EGENERIC;
1541 static void transcode_video_encoder_init( sout_stream_t *p_stream,
1542 sout_stream_id_t *id )
1544 sout_stream_sys_t *p_sys = p_stream->p_sys;
1546 /* Calculate scaling
1547 * width/height of source */
1548 int i_src_width = id->p_decoder->fmt_out.video.i_width;
1549 int i_src_height = id->p_decoder->fmt_out.video.i_height;
1551 /* with/height scaling */
1552 float f_scale_width = 1;
1553 float f_scale_height = 1;
1555 /* width/height of output stream */
1560 float f_aspect = (float)id->p_decoder->fmt_out.video.i_aspect /
1563 msg_Dbg( p_stream, "decoder aspect is %i:%i",
1564 id->p_decoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1566 /* Change f_aspect from source frame to source pixel */
1567 f_aspect = f_aspect * i_src_height / i_src_width;
1568 msg_Dbg( p_stream, "source pixel aspect is %f:1", f_aspect );
1570 /* Calculate scaling factor for specified parameters */
1571 if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1572 id->p_encoder->fmt_out.video.i_height <= 0 && p_sys->f_scale )
1574 /* Global scaling. Make sure width will remain a factor of 16 */
1577 int i_new_width = i_src_width * p_sys->f_scale;
1579 if( i_new_width % 16 <= 7 && i_new_width >= 16 )
1580 i_new_width -= i_new_width % 16;
1582 i_new_width += 16 - i_new_width % 16;
1584 f_real_scale = (float)( i_new_width ) / (float) i_src_width;
1586 i_new_height = __MAX( 16, i_src_height * (float)f_real_scale );
1588 f_scale_width = f_real_scale;
1589 f_scale_height = (float) i_new_height / (float) i_src_height;
1591 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1592 id->p_encoder->fmt_out.video.i_height <= 0 )
1594 /* Only width specified */
1595 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1596 f_scale_height = f_scale_width;
1598 else if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1599 id->p_encoder->fmt_out.video.i_height > 0 )
1601 /* Only height specified */
1602 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1603 f_scale_width = f_scale_height;
1605 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1606 id->p_encoder->fmt_out.video.i_height > 0 )
1608 /* Width and height specified */
1609 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1610 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1613 /* check maxwidth and maxheight
1615 if( p_sys->i_maxwidth && f_scale_width > (float)p_sys->i_maxwidth /
1618 f_scale_width = (float)p_sys->i_maxwidth / i_src_width;
1621 if( p_sys->i_maxheight && f_scale_height > (float)p_sys->i_maxheight /
1624 f_scale_height = (float)p_sys->i_maxheight / i_src_height;
1628 /* Change aspect ratio from source pixel to scaled pixel */
1629 f_aspect = f_aspect * f_scale_height / f_scale_width;
1630 msg_Dbg( p_stream, "scaled pixel aspect is %f:1", f_aspect );
1632 /* f_scale_width and f_scale_height are now final */
1633 /* Calculate width, height from scaling
1634 * Make sure its multiple of 2
1636 i_dst_width = 2 * (int)(f_scale_width*i_src_width/2+0.5);
1637 i_dst_height = 2 * (int)(f_scale_height*i_src_height/2+0.5);
1639 /* Change aspect ratio from scaled pixel to output frame */
1640 f_aspect = f_aspect * i_dst_width / i_dst_height;
1642 /* Store calculated values */
1643 id->p_encoder->fmt_out.video.i_width =
1644 id->p_encoder->fmt_out.video.i_visible_width = i_dst_width;
1645 id->p_encoder->fmt_out.video.i_height =
1646 id->p_encoder->fmt_out.video.i_visible_height = i_dst_height;
1648 id->p_encoder->fmt_in.video.i_width =
1649 id->p_encoder->fmt_in.video.i_visible_width = i_dst_width;
1650 id->p_encoder->fmt_in.video.i_height =
1651 id->p_encoder->fmt_in.video.i_visible_height = i_dst_height;
1653 msg_Dbg( p_stream, "source %ix%i, destination %ix%i",
1654 i_src_width, i_src_height,
1655 i_dst_width, i_dst_height
1658 /* Handle frame rate conversion */
1659 if( !id->p_encoder->fmt_out.video.i_frame_rate ||
1660 !id->p_encoder->fmt_out.video.i_frame_rate_base )
1662 if( id->p_decoder->fmt_out.video.i_frame_rate &&
1663 id->p_decoder->fmt_out.video.i_frame_rate_base )
1665 id->p_encoder->fmt_out.video.i_frame_rate =
1666 id->p_decoder->fmt_out.video.i_frame_rate;
1667 id->p_encoder->fmt_out.video.i_frame_rate_base =
1668 id->p_decoder->fmt_out.video.i_frame_rate_base;
1672 /* Pick a sensible default value */
1673 id->p_encoder->fmt_out.video.i_frame_rate = ENC_FRAMERATE;
1674 id->p_encoder->fmt_out.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1678 id->p_encoder->fmt_in.video.i_frame_rate =
1679 id->p_encoder->fmt_out.video.i_frame_rate;
1680 id->p_encoder->fmt_in.video.i_frame_rate_base =
1681 id->p_encoder->fmt_out.video.i_frame_rate_base;
1683 date_Init( &id->interpolated_pts,
1684 id->p_encoder->fmt_out.video.i_frame_rate,
1685 id->p_encoder->fmt_out.video.i_frame_rate_base );
1687 /* Check whether a particular aspect ratio was requested */
1688 if( !id->p_encoder->fmt_out.video.i_aspect )
1690 id->p_encoder->fmt_out.video.i_aspect =
1691 (int)( f_aspect * VOUT_ASPECT_FACTOR + 0.5 );
1693 id->p_encoder->fmt_in.video.i_aspect =
1694 id->p_encoder->fmt_out.video.i_aspect;
1696 msg_Dbg( p_stream, "encoder aspect is %i:%i",
1697 id->p_encoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1699 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1702 static int transcode_video_encoder_open( sout_stream_t *p_stream,
1703 sout_stream_id_t *id )
1705 sout_stream_sys_t *p_sys = p_stream->p_sys;
1708 msg_Dbg( p_stream, "destination (after video filters) %ix%i",
1709 id->p_encoder->fmt_in.video.i_width,
1710 id->p_encoder->fmt_in.video.i_height );
1712 id->p_encoder->p_module =
1713 module_need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1714 if( !id->p_encoder->p_module )
1716 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1717 p_sys->psz_venc ? p_sys->psz_venc : "any",
1718 (char *)&p_sys->i_vcodec );
1719 return VLC_EGENERIC;
1722 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1725 id->p_encoder->fmt_out.i_codec =
1726 vlc_fourcc_GetCodec( VIDEO_ES, id->p_encoder->fmt_out.i_codec );
1728 id->id = sout_StreamIdAdd( p_stream->p_sys->p_out,
1729 &id->p_encoder->fmt_out );
1732 msg_Err( p_stream, "cannot add this stream" );
1733 return VLC_EGENERIC;
1739 static void transcode_video_close( sout_stream_t *p_stream,
1740 sout_stream_id_t *id )
1742 if( p_stream->p_sys->i_threads >= 1 )
1744 vlc_mutex_lock( &p_stream->p_sys->lock_out );
1745 vlc_object_kill( p_stream->p_sys );
1746 vlc_cond_signal( &p_stream->p_sys->cond );
1747 vlc_mutex_unlock( &p_stream->p_sys->lock_out );
1748 vlc_thread_join( p_stream->p_sys );
1749 vlc_mutex_destroy( &p_stream->p_sys->lock_out );
1750 vlc_cond_destroy( &p_stream->p_sys->cond );
1753 video_timer_close( id->p_encoder );
1756 if( id->p_decoder->p_module )
1757 module_unneed( id->p_decoder, id->p_decoder->p_module );
1758 if( id->p_decoder->p_description )
1759 vlc_meta_Delete( id->p_decoder->p_description );
1761 free( id->p_decoder->p_owner );
1764 if( id->p_encoder->p_module )
1765 module_unneed( id->p_encoder, id->p_encoder->p_module );
1769 filter_chain_Delete( id->p_f_chain );
1770 if( id->p_uf_chain )
1771 filter_chain_Delete( id->p_uf_chain );
1774 static int transcode_video_process( sout_stream_t *p_stream,
1775 sout_stream_id_t *id,
1776 block_t *in, block_t **out )
1778 sout_stream_sys_t *p_sys = p_stream->p_sys;
1779 int i_duplicate = 1;
1780 picture_t *p_pic, *p_pic2 = NULL;
1783 while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
1785 subpicture_t *p_subpic = NULL;
1787 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_VIDEO, 1 );
1789 if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )
1791 mtime_t current_date = mdate();
1792 if( current_date + 50000 > p_pic->date )
1794 msg_Dbg( p_stream, "late picture skipped (%"PRId64")",
1795 current_date + 50000 - p_pic->date );
1796 picture_Release( p_pic );
1801 if( p_sys->b_master_sync )
1803 mtime_t i_video_drift;
1804 mtime_t i_master_drift = p_sys->i_master_drift;
1807 i_pts = date_Get( &id->interpolated_pts ) + 1;
1808 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1809 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
1811 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1812 date_Set( &id->interpolated_pts, p_pic->date );
1813 i_pts = p_pic->date + 1;
1815 i_video_drift = p_pic->date - i_pts;
1818 /* Set the pts of the frame being encoded */
1819 p_pic->date = i_pts;
1821 if( i_video_drift < (i_master_drift - 50000) )
1824 msg_Dbg( p_stream, "dropping frame (%i)",
1825 (int)(i_video_drift - i_master_drift) );
1827 picture_Release( p_pic );
1830 else if( i_video_drift > (i_master_drift + 50000) )
1833 msg_Dbg( p_stream, "adding frame (%i)",
1834 (int)(i_video_drift - i_master_drift) );
1840 if( !id->p_encoder->p_module )
1842 transcode_video_encoder_init( p_stream, id );
1844 id->p_f_chain = filter_chain_New( p_stream, "video filter2",
1846 transcode_video_filter_allocation_init,
1847 transcode_video_filter_allocation_clear,
1851 if( p_stream->p_sys->b_deinterlace )
1853 filter_chain_AppendFilter( id->p_f_chain,
1854 p_sys->psz_deinterlace,
1855 p_sys->p_deinterlace_cfg,
1856 &id->p_decoder->fmt_out,
1857 &id->p_decoder->fmt_out );
1860 /* Take care of the scaling and chroma conversions */
1861 if( ( id->p_decoder->fmt_out.video.i_chroma !=
1862 id->p_encoder->fmt_in.video.i_chroma ) ||
1863 ( id->p_decoder->fmt_out.video.i_width !=
1864 id->p_encoder->fmt_in.video.i_width ) ||
1865 ( id->p_decoder->fmt_out.video.i_height !=
1866 id->p_encoder->fmt_in.video.i_height ) )
1868 filter_chain_AppendFilter( id->p_f_chain,
1870 &id->p_decoder->fmt_out,
1871 &id->p_encoder->fmt_in );
1874 if( p_sys->psz_vf2 )
1876 const es_format_t *p_fmt_out;
1877 id->p_uf_chain = filter_chain_New( p_stream, "video filter2",
1879 transcode_video_filter_allocation_init,
1880 transcode_video_filter_allocation_clear,
1882 filter_chain_Reset( id->p_uf_chain, &id->p_encoder->fmt_in,
1883 &id->p_encoder->fmt_in );
1884 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_vf2 );
1885 p_fmt_out = filter_chain_GetFmtOut( id->p_uf_chain );
1886 es_format_Copy( &id->p_encoder->fmt_in, p_fmt_out );
1887 id->p_encoder->fmt_out.video.i_width =
1888 id->p_encoder->fmt_in.video.i_width;
1889 id->p_encoder->fmt_out.video.i_height =
1890 id->p_encoder->fmt_in.video.i_height;
1891 id->p_encoder->fmt_out.video.i_aspect =
1892 id->p_encoder->fmt_in.video.i_aspect;
1895 if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS )
1897 picture_Release( p_pic );
1898 transcode_video_close( p_stream, id );
1899 id->b_transcode = false;
1900 return VLC_EGENERIC;
1904 /* Run filter chain */
1906 p_pic = filter_chain_VideoFilter( id->p_f_chain, p_pic );
1912 /* Check if we have a subpicture to overlay */
1915 p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date, false );
1916 /* TODO: get another pic */
1919 /* Overlay subpicture */
1924 if( picture_IsReferenced( p_pic ) && !filter_chain_GetLength( id->p_f_chain ) )
1926 /* We can't modify the picture, we need to duplicate it */
1927 picture_t *p_tmp = video_new_buffer_decoder( id->p_decoder );
1930 picture_Copy( p_tmp, p_pic );
1931 picture_Release( p_pic );
1936 if( filter_chain_GetLength( id->p_f_chain ) > 0 )
1937 fmt = filter_chain_GetFmtOut( id->p_f_chain )->video;
1939 fmt = id->p_decoder->fmt_out.video;
1941 /* FIXME (shouldn't have to be done here) */
1942 fmt.i_sar_num = fmt.i_aspect * fmt.i_height / fmt.i_width;
1943 fmt.i_sar_den = VOUT_ASPECT_FACTOR;
1945 /* FIXME the mdate() seems highly suspicious */
1946 spu_RenderSubpictures( p_sys->p_spu, p_pic, &fmt,
1947 p_subpic, &id->p_decoder->fmt_out.video, mdate() );
1950 /* Run user specified filter chain */
1951 if( id->p_uf_chain )
1952 p_pic = filter_chain_VideoFilter( id->p_uf_chain, p_pic );
1954 if( p_sys->i_threads == 0 )
1958 video_timer_start( id->p_encoder );
1959 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
1960 video_timer_stop( id->p_encoder );
1962 block_ChainAppend( out, p_block );
1965 if( p_sys->b_master_sync )
1967 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
1968 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1969 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
1971 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1972 date_Set( &id->interpolated_pts, p_pic->date );
1973 i_pts = p_pic->date + 1;
1975 date_Increment( &id->interpolated_pts, 1 );
1978 if( p_sys->b_master_sync && i_duplicate > 1 )
1980 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
1981 if( (p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT)
1982 || ((p_pic->date - i_pts) < -MASTER_SYNC_MAX_DRIFT) )
1984 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1985 date_Set( &id->interpolated_pts, p_pic->date );
1986 i_pts = p_pic->date + 1;
1988 date_Increment( &id->interpolated_pts, 1 );
1990 if( p_sys->i_threads >= 1 )
1992 /* We can't modify the picture, we need to duplicate it */
1993 p_pic2 = video_new_buffer_decoder( id->p_decoder );
1994 if( p_pic2 != NULL )
1996 picture_Copy( p_pic2, p_pic );
1997 p_pic2->date = i_pts;
2003 p_pic->date = i_pts;
2004 video_timer_start( id->p_encoder );
2005 p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);
2006 video_timer_stop( id->p_encoder );
2007 block_ChainAppend( out, p_block );
2011 if( p_sys->i_threads == 0 )
2013 picture_Release( p_pic );
2017 vlc_mutex_lock( &p_sys->lock_out );
2018 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
2019 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2020 *out = p_sys->p_buffers;
2021 p_sys->p_buffers = NULL;
2022 if( p_pic2 != NULL )
2024 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic2;
2025 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2027 vlc_cond_signal( &p_sys->cond );
2028 vlc_mutex_unlock( &p_sys->lock_out );
2035 static void* EncoderThread( vlc_object_t* p_this )
2037 sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_this;
2038 sout_stream_id_t *id = p_sys->id_video;
2040 int canc = vlc_savecancel ();
2042 while( vlc_object_alive (p_sys) && !p_sys->b_error )
2046 vlc_mutex_lock( &p_sys->lock_out );
2047 while( p_sys->i_last_pic == p_sys->i_first_pic )
2049 vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );
2050 if( !vlc_object_alive (p_sys) || p_sys->b_error ) break;
2052 if( !vlc_object_alive (p_sys) || p_sys->b_error )
2054 vlc_mutex_unlock( &p_sys->lock_out );
2058 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2059 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2060 vlc_mutex_unlock( &p_sys->lock_out );
2062 video_timer_start( id->p_encoder );
2063 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2064 video_timer_stop( id->p_encoder );
2066 vlc_mutex_lock( &p_sys->lock_out );
2067 block_ChainAppend( &p_sys->p_buffers, p_block );
2069 vlc_mutex_unlock( &p_sys->lock_out );
2070 picture_Release( p_pic );
2073 while( p_sys->i_last_pic != p_sys->i_first_pic )
2075 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2076 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2077 picture_Release( p_pic );
2079 block_ChainRelease( p_sys->p_buffers );
2081 vlc_restorecancel (canc);
2085 static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
2087 sout_stream_sys_t *p_ssys = p_dec->p_owner->p_sys;
2088 if( p_ssys->i_threads >= 1 )
2090 int i_first_pic = p_ssys->i_first_pic;
2092 if( p_ssys->i_first_pic != p_ssys->i_last_pic )
2094 /* Encoder still has stuff to encode, wait to clear-up the list */
2095 while( p_ssys->i_first_pic == i_first_pic )
2097 #warning THERE IS A DEFINITELY BUG! LOCKING IS INSUFFICIENT!
2104 p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
2105 return picture_New( p_dec->fmt_out.video.i_chroma,
2106 p_dec->fmt_out.video.i_width,
2107 p_dec->fmt_out.video.i_height,
2108 p_dec->fmt_out.video.i_aspect );
2111 static void video_del_buffer_decoder( decoder_t *p_decoder, picture_t *p_pic )
2113 VLC_UNUSED(p_decoder);
2114 picture_Release( p_pic );
2117 static void video_link_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2120 picture_Hold( p_pic );
2123 static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2126 picture_Release( p_pic );
2132 static subpicture_t *spu_new_buffer( decoder_t * );
2133 static void spu_del_buffer( decoder_t *, subpicture_t * );
2135 static int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2137 sout_stream_sys_t *p_sys = p_stream->p_sys;
2143 /* Initialization of decoder structures */
2144 id->p_decoder->pf_decode_sub = NULL;
2145 id->p_decoder->pf_spu_buffer_new = spu_new_buffer;
2146 id->p_decoder->pf_spu_buffer_del = spu_del_buffer;
2147 id->p_decoder->p_owner = (decoder_owner_sys_t *)p_stream;
2148 /* id->p_decoder->p_cfg = p_sys->p_spu_cfg; */
2150 id->p_decoder->p_module =
2151 module_need( id->p_decoder, "decoder", "$codec", false );
2153 if( !id->p_decoder->p_module )
2155 msg_Err( p_stream, "cannot find spu decoder" );
2156 return VLC_EGENERIC;
2159 if( !p_sys->b_soverlay )
2162 /* Initialization of encoder format structures */
2163 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2164 id->p_decoder->fmt_in.i_codec );
2166 id->p_encoder->p_cfg = p_sys->p_spu_cfg;
2168 id->p_encoder->p_module =
2169 module_need( id->p_encoder, "encoder", p_sys->psz_senc, true );
2171 if( !id->p_encoder->p_module )
2173 module_unneed( id->p_decoder, id->p_decoder->p_module );
2174 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_senc );
2175 return VLC_EGENERIC;
2181 p_sys->p_spu = spu_Create( p_stream );
2182 spu_Init( p_sys->p_spu );
2188 static void transcode_spu_close( sout_stream_id_t *id)
2191 if( id->p_decoder->p_module )
2192 module_unneed( id->p_decoder, id->p_decoder->p_module );
2193 if( id->p_decoder->p_description )
2194 vlc_meta_Delete( id->p_decoder->p_description );
2197 if( id->p_encoder->p_module )
2198 module_unneed( id->p_encoder, id->p_encoder->p_module );
2201 static int transcode_spu_process( sout_stream_t *p_stream,
2202 sout_stream_id_t *id,
2203 block_t *in, block_t **out )
2205 sout_stream_sys_t *p_sys = p_stream->p_sys;
2206 subpicture_t *p_subpic;
2209 p_subpic = id->p_decoder->pf_decode_sub( id->p_decoder, &in );
2211 return VLC_EGENERIC;
2213 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_SUBTITLE, 1 );
2215 if( p_sys->b_master_sync && p_sys->i_master_drift )
2217 p_subpic->i_start -= p_sys->i_master_drift;
2218 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2221 if( p_sys->b_soverlay )
2223 spu_DisplaySubpicture( p_sys->p_spu, p_subpic );
2229 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2230 spu_del_buffer( id->p_decoder, p_subpic );
2233 block_ChainAppend( out, p_block );
2238 return VLC_EGENERIC;
2241 static subpicture_t *spu_new_buffer( decoder_t *p_dec )
2243 VLC_UNUSED( p_dec );
2244 return subpicture_New();
2247 static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
2249 VLC_UNUSED( p_dec );
2250 subpicture_Delete( p_subpic );
2256 static int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2258 sout_stream_sys_t *p_sys = p_stream->p_sys;
2260 id->p_decoder->fmt_in.i_cat = SPU_ES;
2261 id->p_encoder->fmt_out.psz_language = strdup( "osd" );
2263 if( p_sys->i_osdcodec != 0 || p_sys->psz_osdenc )
2265 msg_Dbg( p_stream, "creating osdmenu transcoding from fcc=`%4.4s' "
2266 "to fcc=`%4.4s'", (char*)&id->p_encoder->fmt_out.i_codec,
2267 (char*)&p_sys->i_osdcodec );
2269 /* Complete destination format */
2270 id->p_encoder->fmt_out.i_codec = p_sys->i_osdcodec;
2273 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2275 id->p_encoder->fmt_in.psz_language = strdup( "osd" );
2277 id->p_encoder->p_cfg = p_sys->p_osd_cfg;
2279 id->p_encoder->p_module =
2280 module_need( id->p_encoder, "encoder", p_sys->psz_osdenc, true );
2282 if( !id->p_encoder->p_module )
2284 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_osdenc );
2288 /* open output stream */
2289 id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_encoder->fmt_out );
2290 id->b_transcode = true;
2292 if( !id->id ) goto error;
2296 msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
2297 (char*)&id->p_decoder->fmt_out.i_codec );
2298 id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_decoder->fmt_out );
2299 id->b_transcode = false;
2301 if( !id->id ) goto error;
2306 p_sys->p_spu = spu_Create( p_stream );
2307 spu_Init( p_sys->p_spu );
2313 msg_Err( p_stream, "starting osd encoding thread failed" );
2314 if( id->p_encoder->p_module )
2315 module_unneed( id->p_encoder, id->p_encoder->p_module );
2316 p_sys->b_osd = false;
2317 return VLC_EGENERIC;
2320 static void transcode_osd_close( sout_stream_t *p_stream, sout_stream_id_t *id)
2322 sout_stream_sys_t *p_sys = p_stream->p_sys;
2327 if( id->p_encoder->p_module )
2328 module_unneed( id->p_encoder, id->p_encoder->p_module );
2330 p_sys->b_osd = false;
2333 static int transcode_osd_process( sout_stream_t *p_stream,
2334 sout_stream_id_t *id,
2335 block_t *in, block_t **out )
2337 sout_stream_sys_t *p_sys = p_stream->p_sys;
2338 subpicture_t *p_subpic = NULL;
2340 /* Check if we have a subpicture to send */
2341 if( p_sys->p_spu && in->i_dts > 0)
2343 p_subpic = spu_SortSubpictures( p_sys->p_spu, in->i_dts, false );
2347 msg_Warn( p_stream, "spu channel not initialized, doing it now" );
2350 p_sys->p_spu = spu_Create( p_stream );
2351 spu_Init( p_sys->p_spu );
2357 block_t *p_block = NULL;
2359 if( p_sys->b_master_sync && p_sys->i_master_drift )
2361 p_subpic->i_start -= p_sys->i_master_drift;
2362 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2365 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2366 subpicture_Delete( p_subpic );
2369 p_block->i_dts = p_block->i_pts = in->i_dts;
2370 block_ChainAppend( out, p_block );
2374 return VLC_EGENERIC;