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", false, 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", false, 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", false, 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", false, 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", false, 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->i_pts - i_dts > MASTER_SYNC_MAX_DRIFT
1299 || p_audio_buf->i_pts - 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->i_pts );
1303 i_dts = p_audio_buf->i_pts + 1;
1305 p_sys->i_master_drift = p_audio_buf->i_pts - i_dts;
1306 date_Increment( &id->interpolated_pts, p_audio_buf->i_nb_samples );
1307 p_audio_buf->i_pts -= p_sys->i_master_drift;
1310 p_audio_block = p_audio_buf->p_sys;
1311 p_audio_block->i_buffer = p_audio_buf->i_buffer;
1312 p_audio_block->i_dts = p_audio_block->i_pts =
1314 p_audio_block->i_length = p_audio_buf->i_length;
1315 p_audio_block->i_nb_samples = p_audio_buf->i_nb_samples;
1317 /* Run filter chain */
1318 if( id->p_uf_chain )
1320 p_audio_block = filter_chain_AudioFilter( id->p_uf_chain, p_audio_block );
1321 assert( p_audio_block );
1324 p_audio_block = filter_chain_AudioFilter( id->p_f_chain, p_audio_block );
1325 assert( p_audio_block );
1327 p_audio_buf->p_buffer = p_audio_block->p_buffer;
1328 p_audio_buf->i_buffer = p_audio_block->i_buffer;
1329 p_audio_buf->i_nb_samples = p_audio_block->i_nb_samples;
1330 p_audio_buf->i_pts = p_audio_block->i_dts;
1331 p_audio_buf->i_length = p_audio_block->i_length;
1333 audio_timer_start( id->p_encoder );
1334 p_block = id->p_encoder->pf_encode_audio( id->p_encoder, p_audio_buf );
1335 audio_timer_stop( id->p_encoder );
1337 block_ChainAppend( out, p_block );
1338 block_Release( p_audio_block );
1339 free( p_audio_buf );
1345 static aout_buffer_t *audio_new_buffer( decoder_t *p_dec, int i_samples )
1347 aout_buffer_t *p_buffer;
1351 if( p_dec->fmt_out.audio.i_bitspersample )
1353 i_size = i_samples * p_dec->fmt_out.audio.i_bitspersample / 8 *
1354 p_dec->fmt_out.audio.i_channels;
1356 else if( p_dec->fmt_out.audio.i_bytes_per_frame &&
1357 p_dec->fmt_out.audio.i_frame_length )
1359 i_size = i_samples * p_dec->fmt_out.audio.i_bytes_per_frame /
1360 p_dec->fmt_out.audio.i_frame_length;
1364 i_size = i_samples * 4 * p_dec->fmt_out.audio.i_channels;
1367 p_buffer = malloc( sizeof(aout_buffer_t) );
1368 if( !p_buffer ) return NULL;
1369 p_buffer->i_flags = 0;
1370 p_buffer->p_sys = p_block = block_New( p_dec, i_size );
1372 p_buffer->p_buffer = p_block->p_buffer;
1373 p_buffer->i_size = p_buffer->i_buffer = p_block->i_buffer;
1374 p_buffer->i_nb_samples = i_samples;
1375 p_block->i_nb_samples = i_samples;
1380 static void audio_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
1383 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1391 static picture_t *transcode_video_filter_buffer_new( filter_t *p_filter )
1393 p_filter->fmt_out.video.i_chroma = p_filter->fmt_out.i_codec;
1394 return picture_New( p_filter->fmt_out.video.i_chroma,
1395 p_filter->fmt_out.video.i_width,
1396 p_filter->fmt_out.video.i_height,
1397 p_filter->fmt_out.video.i_aspect );
1399 static void transcode_video_filter_buffer_del( filter_t *p_filter, picture_t *p_pic )
1401 VLC_UNUSED(p_filter);
1402 picture_Release( p_pic );
1405 static int transcode_video_filter_allocation_init( filter_t *p_filter,
1409 p_filter->pf_vout_buffer_new = transcode_video_filter_buffer_new;
1410 p_filter->pf_vout_buffer_del = transcode_video_filter_buffer_del;
1414 static void transcode_video_filter_allocation_clear( filter_t *p_filter )
1416 VLC_UNUSED(p_filter);
1419 static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
1421 sout_stream_sys_t *p_sys = p_stream->p_sys;
1424 * Initialization of decoder structures
1426 id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1427 id->p_decoder->fmt_out.i_extra = 0;
1428 id->p_decoder->fmt_out.p_extra = 0;
1429 id->p_decoder->pf_decode_video = NULL;
1430 id->p_decoder->pf_get_cc = NULL;
1431 id->p_decoder->pf_get_cc = 0;
1432 id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
1433 id->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder;
1434 id->p_decoder->pf_picture_link = video_link_picture_decoder;
1435 id->p_decoder->pf_picture_unlink = video_unlink_picture_decoder;
1436 id->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) );
1437 if( !id->p_decoder->p_owner )
1438 return VLC_EGENERIC;
1440 id->p_decoder->p_owner->p_sys = p_sys;
1441 /* id->p_decoder->p_cfg = p_sys->p_video_cfg; */
1443 id->p_decoder->p_module =
1444 module_need( id->p_decoder, "decoder", "$codec", false );
1446 if( !id->p_decoder->p_module )
1448 msg_Err( p_stream, "cannot find video decoder" );
1449 free( id->p_decoder->p_owner );
1450 return VLC_EGENERIC;
1455 * Because some info about the decoded input will only be available
1456 * once the first frame is decoded, we actually only test the availability
1457 * of the encoder here.
1460 /* Initialization of encoder format structures */
1461 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1462 id->p_decoder->fmt_out.i_codec );
1463 id->p_encoder->fmt_in.video.i_chroma = id->p_decoder->fmt_out.i_codec;
1465 /* The dimensions will be set properly later on.
1466 * Just put sensible values so we can test an encoder is available. */
1467 id->p_encoder->fmt_in.video.i_width =
1468 id->p_encoder->fmt_out.video.i_width
1469 ? id->p_encoder->fmt_out.video.i_width
1470 : id->p_decoder->fmt_in.video.i_width
1471 ? id->p_decoder->fmt_in.video.i_width : 16;
1472 id->p_encoder->fmt_in.video.i_height =
1473 id->p_encoder->fmt_out.video.i_height
1474 ? id->p_encoder->fmt_out.video.i_height
1475 : id->p_decoder->fmt_in.video.i_height
1476 ? id->p_decoder->fmt_in.video.i_height : 16;
1477 id->p_encoder->fmt_in.video.i_frame_rate = ENC_FRAMERATE;
1478 id->p_encoder->fmt_in.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1480 id->p_encoder->i_threads = p_sys->i_threads;
1481 id->p_encoder->p_cfg = p_sys->p_video_cfg;
1483 id->p_encoder->p_module =
1484 module_need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1485 if( !id->p_encoder->p_module )
1487 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1488 p_sys->psz_venc ? p_sys->psz_venc : "any",
1489 (char *)&p_sys->i_vcodec );
1490 module_unneed( id->p_decoder, id->p_decoder->p_module );
1491 id->p_decoder->p_module = 0;
1492 free( id->p_decoder->p_owner );
1493 return VLC_EGENERIC;
1496 /* Close the encoder.
1497 * We'll open it only when we have the first frame. */
1498 module_unneed( id->p_encoder, id->p_encoder->p_module );
1499 if( id->p_encoder->fmt_out.p_extra )
1501 free( id->p_encoder->fmt_out.p_extra );
1502 id->p_encoder->fmt_out.p_extra = NULL;
1503 id->p_encoder->fmt_out.i_extra = 0;
1505 id->p_encoder->p_module = NULL;
1507 if( p_sys->i_threads >= 1 )
1509 int i_priority = p_sys->b_high_priority ? VLC_THREAD_PRIORITY_OUTPUT :
1510 VLC_THREAD_PRIORITY_VIDEO;
1511 p_sys->id_video = id;
1512 vlc_mutex_init( &p_sys->lock_out );
1513 vlc_cond_init( &p_sys->cond );
1514 memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) );
1515 p_sys->i_first_pic = 0;
1516 p_sys->i_last_pic = 0;
1517 p_sys->p_buffers = NULL;
1518 p_sys->b_die = p_sys->b_error = 0;
1519 if( vlc_thread_create( p_sys, "encoder", EncoderThread, i_priority ) )
1521 msg_Err( p_stream, "cannot spawn encoder thread" );
1522 module_unneed( id->p_decoder, id->p_decoder->p_module );
1523 id->p_decoder->p_module = 0;
1524 free( id->p_decoder->p_owner );
1525 return VLC_EGENERIC;
1532 static void transcode_video_encoder_init( sout_stream_t *p_stream,
1533 sout_stream_id_t *id )
1535 sout_stream_sys_t *p_sys = p_stream->p_sys;
1537 /* Calculate scaling
1538 * width/height of source */
1539 int i_src_width = id->p_decoder->fmt_out.video.i_width;
1540 int i_src_height = id->p_decoder->fmt_out.video.i_height;
1542 /* with/height scaling */
1543 float f_scale_width = 1;
1544 float f_scale_height = 1;
1546 /* width/height of output stream */
1551 float f_aspect = (float)id->p_decoder->fmt_out.video.i_aspect /
1554 msg_Dbg( p_stream, "decoder aspect is %i:%i",
1555 id->p_decoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1557 /* Change f_aspect from source frame to source pixel */
1558 f_aspect = f_aspect * i_src_height / i_src_width;
1559 msg_Dbg( p_stream, "source pixel aspect is %f:1", f_aspect );
1561 /* Calculate scaling factor for specified parameters */
1562 if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1563 id->p_encoder->fmt_out.video.i_height <= 0 && p_sys->f_scale )
1565 /* Global scaling. Make sure width will remain a factor of 16 */
1568 int i_new_width = i_src_width * p_sys->f_scale;
1570 if( i_new_width % 16 <= 7 && i_new_width >= 16 )
1571 i_new_width -= i_new_width % 16;
1573 i_new_width += 16 - i_new_width % 16;
1575 f_real_scale = (float)( i_new_width ) / (float) i_src_width;
1577 i_new_height = __MAX( 16, i_src_height * (float)f_real_scale );
1579 f_scale_width = f_real_scale;
1580 f_scale_height = (float) i_new_height / (float) i_src_height;
1582 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1583 id->p_encoder->fmt_out.video.i_height <= 0 )
1585 /* Only width specified */
1586 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1587 f_scale_height = f_scale_width;
1589 else if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1590 id->p_encoder->fmt_out.video.i_height > 0 )
1592 /* Only height specified */
1593 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1594 f_scale_width = f_scale_height;
1596 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1597 id->p_encoder->fmt_out.video.i_height > 0 )
1599 /* Width and height specified */
1600 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1601 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1604 /* check maxwidth and maxheight
1606 if( p_sys->i_maxwidth && f_scale_width > (float)p_sys->i_maxwidth /
1609 f_scale_width = (float)p_sys->i_maxwidth / i_src_width;
1612 if( p_sys->i_maxheight && f_scale_height > (float)p_sys->i_maxheight /
1615 f_scale_height = (float)p_sys->i_maxheight / i_src_height;
1619 /* Change aspect ratio from source pixel to scaled pixel */
1620 f_aspect = f_aspect * f_scale_height / f_scale_width;
1621 msg_Dbg( p_stream, "scaled pixel aspect is %f:1", f_aspect );
1623 /* f_scale_width and f_scale_height are now final */
1624 /* Calculate width, height from scaling
1625 * Make sure its multiple of 2
1627 i_dst_width = 2 * (int)(f_scale_width*i_src_width/2+0.5);
1628 i_dst_height = 2 * (int)(f_scale_height*i_src_height/2+0.5);
1630 /* Change aspect ratio from scaled pixel to output frame */
1631 f_aspect = f_aspect * i_dst_width / i_dst_height;
1633 /* Store calculated values */
1634 id->p_encoder->fmt_out.video.i_width =
1635 id->p_encoder->fmt_out.video.i_visible_width = i_dst_width;
1636 id->p_encoder->fmt_out.video.i_height =
1637 id->p_encoder->fmt_out.video.i_visible_height = i_dst_height;
1639 id->p_encoder->fmt_in.video.i_width =
1640 id->p_encoder->fmt_in.video.i_visible_width = i_dst_width;
1641 id->p_encoder->fmt_in.video.i_height =
1642 id->p_encoder->fmt_in.video.i_visible_height = i_dst_height;
1644 msg_Dbg( p_stream, "source %ix%i, destination %ix%i",
1645 i_src_width, i_src_height,
1646 i_dst_width, i_dst_height
1649 /* Handle frame rate conversion */
1650 if( !id->p_encoder->fmt_out.video.i_frame_rate ||
1651 !id->p_encoder->fmt_out.video.i_frame_rate_base )
1653 if( id->p_decoder->fmt_out.video.i_frame_rate &&
1654 id->p_decoder->fmt_out.video.i_frame_rate_base )
1656 id->p_encoder->fmt_out.video.i_frame_rate =
1657 id->p_decoder->fmt_out.video.i_frame_rate;
1658 id->p_encoder->fmt_out.video.i_frame_rate_base =
1659 id->p_decoder->fmt_out.video.i_frame_rate_base;
1663 /* Pick a sensible default value */
1664 id->p_encoder->fmt_out.video.i_frame_rate = ENC_FRAMERATE;
1665 id->p_encoder->fmt_out.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1669 id->p_encoder->fmt_in.video.i_frame_rate =
1670 id->p_encoder->fmt_out.video.i_frame_rate;
1671 id->p_encoder->fmt_in.video.i_frame_rate_base =
1672 id->p_encoder->fmt_out.video.i_frame_rate_base;
1674 date_Init( &id->interpolated_pts,
1675 id->p_encoder->fmt_out.video.i_frame_rate,
1676 id->p_encoder->fmt_out.video.i_frame_rate_base );
1678 /* Check whether a particular aspect ratio was requested */
1679 if( !id->p_encoder->fmt_out.video.i_aspect )
1681 id->p_encoder->fmt_out.video.i_aspect =
1682 (int)( f_aspect * VOUT_ASPECT_FACTOR + 0.5 );
1684 id->p_encoder->fmt_in.video.i_aspect =
1685 id->p_encoder->fmt_out.video.i_aspect;
1687 msg_Dbg( p_stream, "encoder aspect is %i:%i",
1688 id->p_encoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1690 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1693 static int transcode_video_encoder_open( sout_stream_t *p_stream,
1694 sout_stream_id_t *id )
1696 sout_stream_sys_t *p_sys = p_stream->p_sys;
1699 msg_Dbg( p_stream, "destination (after video filters) %ix%i",
1700 id->p_encoder->fmt_in.video.i_width,
1701 id->p_encoder->fmt_in.video.i_height );
1703 id->p_encoder->p_module =
1704 module_need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1705 if( !id->p_encoder->p_module )
1707 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1708 p_sys->psz_venc ? p_sys->psz_venc : "any",
1709 (char *)&p_sys->i_vcodec );
1710 return VLC_EGENERIC;
1713 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1716 id->p_encoder->fmt_out.i_codec =
1717 vlc_fourcc_GetCodec( VIDEO_ES, id->p_encoder->fmt_out.i_codec );
1719 id->id = sout_StreamIdAdd( p_stream->p_sys->p_out,
1720 &id->p_encoder->fmt_out );
1723 msg_Err( p_stream, "cannot add this stream" );
1724 return VLC_EGENERIC;
1730 static void transcode_video_close( sout_stream_t *p_stream,
1731 sout_stream_id_t *id )
1733 if( p_stream->p_sys->i_threads >= 1 )
1735 vlc_mutex_lock( &p_stream->p_sys->lock_out );
1736 vlc_object_kill( p_stream->p_sys );
1737 vlc_cond_signal( &p_stream->p_sys->cond );
1738 vlc_mutex_unlock( &p_stream->p_sys->lock_out );
1739 vlc_thread_join( p_stream->p_sys );
1740 vlc_mutex_destroy( &p_stream->p_sys->lock_out );
1741 vlc_cond_destroy( &p_stream->p_sys->cond );
1744 video_timer_close( id->p_encoder );
1747 if( id->p_decoder->p_module )
1748 module_unneed( id->p_decoder, id->p_decoder->p_module );
1749 if( id->p_decoder->p_description )
1750 vlc_meta_Delete( id->p_decoder->p_description );
1752 free( id->p_decoder->p_owner );
1755 if( id->p_encoder->p_module )
1756 module_unneed( id->p_encoder, id->p_encoder->p_module );
1760 filter_chain_Delete( id->p_f_chain );
1761 if( id->p_uf_chain )
1762 filter_chain_Delete( id->p_uf_chain );
1765 static int transcode_video_process( sout_stream_t *p_stream,
1766 sout_stream_id_t *id,
1767 block_t *in, block_t **out )
1769 sout_stream_sys_t *p_sys = p_stream->p_sys;
1770 int i_duplicate = 1;
1771 picture_t *p_pic, *p_pic2 = NULL;
1774 while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
1776 subpicture_t *p_subpic = NULL;
1778 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_VIDEO, 1 );
1780 if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )
1782 mtime_t current_date = mdate();
1783 if( current_date + 50000 > p_pic->date )
1785 msg_Dbg( p_stream, "late picture skipped (%"PRId64")",
1786 current_date + 50000 - p_pic->date );
1787 picture_Release( p_pic );
1792 if( p_sys->b_master_sync )
1794 mtime_t i_video_drift;
1795 mtime_t i_master_drift = p_sys->i_master_drift;
1798 i_pts = date_Get( &id->interpolated_pts ) + 1;
1799 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1800 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
1802 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1803 date_Set( &id->interpolated_pts, p_pic->date );
1804 i_pts = p_pic->date + 1;
1806 i_video_drift = p_pic->date - i_pts;
1809 /* Set the pts of the frame being encoded */
1810 p_pic->date = i_pts;
1812 if( i_video_drift < (i_master_drift - 50000) )
1815 msg_Dbg( p_stream, "dropping frame (%i)",
1816 (int)(i_video_drift - i_master_drift) );
1818 picture_Release( p_pic );
1821 else if( i_video_drift > (i_master_drift + 50000) )
1824 msg_Dbg( p_stream, "adding frame (%i)",
1825 (int)(i_video_drift - i_master_drift) );
1831 if( !id->p_encoder->p_module )
1833 transcode_video_encoder_init( p_stream, id );
1835 id->p_f_chain = filter_chain_New( p_stream, "video filter2",
1837 transcode_video_filter_allocation_init,
1838 transcode_video_filter_allocation_clear,
1842 if( p_stream->p_sys->b_deinterlace )
1844 filter_chain_AppendFilter( id->p_f_chain,
1845 p_sys->psz_deinterlace,
1846 p_sys->p_deinterlace_cfg,
1847 &id->p_decoder->fmt_out,
1848 &id->p_decoder->fmt_out );
1851 /* Take care of the scaling and chroma conversions */
1852 if( ( id->p_decoder->fmt_out.video.i_chroma !=
1853 id->p_encoder->fmt_in.video.i_chroma ) ||
1854 ( id->p_decoder->fmt_out.video.i_width !=
1855 id->p_encoder->fmt_in.video.i_width ) ||
1856 ( id->p_decoder->fmt_out.video.i_height !=
1857 id->p_encoder->fmt_in.video.i_height ) )
1859 filter_chain_AppendFilter( id->p_f_chain,
1861 &id->p_decoder->fmt_out,
1862 &id->p_encoder->fmt_in );
1865 if( p_sys->psz_vf2 )
1867 const es_format_t *p_fmt_out;
1868 id->p_uf_chain = filter_chain_New( p_stream, "video filter2",
1870 transcode_video_filter_allocation_init,
1871 transcode_video_filter_allocation_clear,
1873 filter_chain_Reset( id->p_uf_chain, &id->p_encoder->fmt_in,
1874 &id->p_encoder->fmt_in );
1875 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_vf2 );
1876 p_fmt_out = filter_chain_GetFmtOut( id->p_uf_chain );
1877 es_format_Copy( &id->p_encoder->fmt_in, p_fmt_out );
1878 id->p_encoder->fmt_out.video.i_width =
1879 id->p_encoder->fmt_in.video.i_width;
1880 id->p_encoder->fmt_out.video.i_height =
1881 id->p_encoder->fmt_in.video.i_height;
1882 id->p_encoder->fmt_out.video.i_aspect =
1883 id->p_encoder->fmt_in.video.i_aspect;
1886 if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS )
1888 picture_Release( p_pic );
1889 transcode_video_close( p_stream, id );
1890 id->b_transcode = false;
1891 return VLC_EGENERIC;
1895 /* Run filter chain */
1897 p_pic = filter_chain_VideoFilter( id->p_f_chain, p_pic );
1903 /* Check if we have a subpicture to overlay */
1906 p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date, false );
1907 /* TODO: get another pic */
1910 /* Overlay subpicture */
1915 if( picture_IsReferenced( p_pic ) && !filter_chain_GetLength( id->p_f_chain ) )
1917 /* We can't modify the picture, we need to duplicate it */
1918 picture_t *p_tmp = video_new_buffer_decoder( id->p_decoder );
1921 picture_Copy( p_tmp, p_pic );
1922 picture_Release( p_pic );
1927 if( filter_chain_GetLength( id->p_f_chain ) > 0 )
1928 fmt = filter_chain_GetFmtOut( id->p_f_chain )->video;
1930 fmt = id->p_decoder->fmt_out.video;
1932 /* FIXME (shouldn't have to be done here) */
1933 fmt.i_sar_num = fmt.i_aspect * fmt.i_height / fmt.i_width;
1934 fmt.i_sar_den = VOUT_ASPECT_FACTOR;
1936 /* FIXME the mdate() seems highly suspicious */
1937 spu_RenderSubpictures( p_sys->p_spu, p_pic, &fmt,
1938 p_subpic, &id->p_decoder->fmt_out.video, mdate() );
1941 /* Run user specified filter chain */
1942 if( id->p_uf_chain )
1943 p_pic = filter_chain_VideoFilter( id->p_uf_chain, p_pic );
1945 if( p_sys->i_threads == 0 )
1949 video_timer_start( id->p_encoder );
1950 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
1951 video_timer_stop( id->p_encoder );
1953 block_ChainAppend( out, p_block );
1956 if( p_sys->b_master_sync )
1958 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
1959 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1960 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
1962 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1963 date_Set( &id->interpolated_pts, p_pic->date );
1964 i_pts = p_pic->date + 1;
1966 date_Increment( &id->interpolated_pts, 1 );
1969 if( p_sys->b_master_sync && i_duplicate > 1 )
1971 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
1972 if( (p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT)
1973 || ((p_pic->date - i_pts) < -MASTER_SYNC_MAX_DRIFT) )
1975 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1976 date_Set( &id->interpolated_pts, p_pic->date );
1977 i_pts = p_pic->date + 1;
1979 date_Increment( &id->interpolated_pts, 1 );
1981 if( p_sys->i_threads >= 1 )
1983 /* We can't modify the picture, we need to duplicate it */
1984 p_pic2 = video_new_buffer_decoder( id->p_decoder );
1985 if( p_pic2 != NULL )
1987 picture_Copy( p_pic2, p_pic );
1988 p_pic2->date = i_pts;
1994 p_pic->date = i_pts;
1995 video_timer_start( id->p_encoder );
1996 p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);
1997 video_timer_stop( id->p_encoder );
1998 block_ChainAppend( out, p_block );
2002 if( p_sys->i_threads == 0 )
2004 picture_Release( p_pic );
2008 vlc_mutex_lock( &p_sys->lock_out );
2009 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
2010 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2011 *out = p_sys->p_buffers;
2012 p_sys->p_buffers = NULL;
2013 if( p_pic2 != NULL )
2015 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic2;
2016 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2018 vlc_cond_signal( &p_sys->cond );
2019 vlc_mutex_unlock( &p_sys->lock_out );
2026 static void* EncoderThread( vlc_object_t* p_this )
2028 sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_this;
2029 sout_stream_id_t *id = p_sys->id_video;
2031 int canc = vlc_savecancel ();
2033 while( vlc_object_alive (p_sys) && !p_sys->b_error )
2037 vlc_mutex_lock( &p_sys->lock_out );
2038 while( p_sys->i_last_pic == p_sys->i_first_pic )
2040 vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );
2041 if( !vlc_object_alive (p_sys) || p_sys->b_error ) break;
2043 if( !vlc_object_alive (p_sys) || p_sys->b_error )
2045 vlc_mutex_unlock( &p_sys->lock_out );
2049 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2050 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2051 vlc_mutex_unlock( &p_sys->lock_out );
2053 video_timer_start( id->p_encoder );
2054 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2055 video_timer_stop( id->p_encoder );
2057 vlc_mutex_lock( &p_sys->lock_out );
2058 block_ChainAppend( &p_sys->p_buffers, p_block );
2060 vlc_mutex_unlock( &p_sys->lock_out );
2061 picture_Release( p_pic );
2064 while( p_sys->i_last_pic != p_sys->i_first_pic )
2066 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2067 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2068 picture_Release( p_pic );
2070 block_ChainRelease( p_sys->p_buffers );
2072 vlc_restorecancel (canc);
2076 static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
2078 sout_stream_sys_t *p_ssys = p_dec->p_owner->p_sys;
2079 if( p_ssys->i_threads >= 1 )
2081 int i_first_pic = p_ssys->i_first_pic;
2083 if( p_ssys->i_first_pic != p_ssys->i_last_pic )
2085 /* Encoder still has stuff to encode, wait to clear-up the list */
2086 while( p_ssys->i_first_pic == i_first_pic )
2088 #warning THERE IS A DEFINITELY BUG! LOCKING IS INSUFFICIENT!
2095 p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
2096 return picture_New( p_dec->fmt_out.video.i_chroma,
2097 p_dec->fmt_out.video.i_width,
2098 p_dec->fmt_out.video.i_height,
2099 p_dec->fmt_out.video.i_aspect );
2102 static void video_del_buffer_decoder( decoder_t *p_decoder, picture_t *p_pic )
2104 VLC_UNUSED(p_decoder);
2105 picture_Release( p_pic );
2108 static void video_link_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2111 picture_Hold( p_pic );
2114 static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2117 picture_Release( p_pic );
2123 static subpicture_t *spu_new_buffer( decoder_t * );
2124 static void spu_del_buffer( decoder_t *, subpicture_t * );
2126 static int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2128 sout_stream_sys_t *p_sys = p_stream->p_sys;
2134 /* Initialization of decoder structures */
2135 id->p_decoder->pf_decode_sub = NULL;
2136 id->p_decoder->pf_spu_buffer_new = spu_new_buffer;
2137 id->p_decoder->pf_spu_buffer_del = spu_del_buffer;
2138 id->p_decoder->p_owner = (decoder_owner_sys_t *)p_stream;
2139 /* id->p_decoder->p_cfg = p_sys->p_spu_cfg; */
2141 id->p_decoder->p_module =
2142 module_need( id->p_decoder, "decoder", "$codec", false );
2144 if( !id->p_decoder->p_module )
2146 msg_Err( p_stream, "cannot find spu decoder" );
2147 return VLC_EGENERIC;
2150 if( !p_sys->b_soverlay )
2153 /* Initialization of encoder format structures */
2154 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2155 id->p_decoder->fmt_in.i_codec );
2157 id->p_encoder->p_cfg = p_sys->p_spu_cfg;
2159 id->p_encoder->p_module =
2160 module_need( id->p_encoder, "encoder", p_sys->psz_senc, true );
2162 if( !id->p_encoder->p_module )
2164 module_unneed( id->p_decoder, id->p_decoder->p_module );
2165 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_senc );
2166 return VLC_EGENERIC;
2172 p_sys->p_spu = spu_Create( p_stream );
2173 spu_Init( p_sys->p_spu );
2179 static void transcode_spu_close( sout_stream_id_t *id)
2182 if( id->p_decoder->p_module )
2183 module_unneed( id->p_decoder, id->p_decoder->p_module );
2184 if( id->p_decoder->p_description )
2185 vlc_meta_Delete( id->p_decoder->p_description );
2188 if( id->p_encoder->p_module )
2189 module_unneed( id->p_encoder, id->p_encoder->p_module );
2192 static int transcode_spu_process( sout_stream_t *p_stream,
2193 sout_stream_id_t *id,
2194 block_t *in, block_t **out )
2196 sout_stream_sys_t *p_sys = p_stream->p_sys;
2197 subpicture_t *p_subpic;
2200 p_subpic = id->p_decoder->pf_decode_sub( id->p_decoder, &in );
2202 return VLC_EGENERIC;
2204 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_SUBTITLE, 1 );
2206 if( p_sys->b_master_sync && p_sys->i_master_drift )
2208 p_subpic->i_start -= p_sys->i_master_drift;
2209 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2212 if( p_sys->b_soverlay )
2214 spu_DisplaySubpicture( p_sys->p_spu, p_subpic );
2220 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2221 spu_del_buffer( id->p_decoder, p_subpic );
2224 block_ChainAppend( out, p_block );
2229 return VLC_EGENERIC;
2232 static subpicture_t *spu_new_buffer( decoder_t *p_dec )
2234 VLC_UNUSED( p_dec );
2235 return subpicture_New();
2238 static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
2240 VLC_UNUSED( p_dec );
2241 subpicture_Delete( p_subpic );
2247 static int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2249 sout_stream_sys_t *p_sys = p_stream->p_sys;
2251 id->p_decoder->fmt_in.i_cat = SPU_ES;
2252 id->p_encoder->fmt_out.psz_language = strdup( "osd" );
2254 if( p_sys->i_osdcodec != 0 || p_sys->psz_osdenc )
2256 msg_Dbg( p_stream, "creating osdmenu transcoding from fcc=`%4.4s' "
2257 "to fcc=`%4.4s'", (char*)&id->p_encoder->fmt_out.i_codec,
2258 (char*)&p_sys->i_osdcodec );
2260 /* Complete destination format */
2261 id->p_encoder->fmt_out.i_codec = p_sys->i_osdcodec;
2264 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2266 id->p_encoder->fmt_in.psz_language = strdup( "osd" );
2268 id->p_encoder->p_cfg = p_sys->p_osd_cfg;
2270 id->p_encoder->p_module =
2271 module_need( id->p_encoder, "encoder", p_sys->psz_osdenc, true );
2273 if( !id->p_encoder->p_module )
2275 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_osdenc );
2279 /* open output stream */
2280 id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_encoder->fmt_out );
2281 id->b_transcode = true;
2283 if( !id->id ) goto error;
2287 msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
2288 (char*)&id->p_decoder->fmt_out.i_codec );
2289 id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_decoder->fmt_out );
2290 id->b_transcode = false;
2292 if( !id->id ) goto error;
2297 p_sys->p_spu = spu_Create( p_stream );
2298 spu_Init( p_sys->p_spu );
2304 msg_Err( p_stream, "starting osd encoding thread failed" );
2305 if( id->p_encoder->p_module )
2306 module_unneed( id->p_encoder, id->p_encoder->p_module );
2307 p_sys->b_osd = false;
2308 return VLC_EGENERIC;
2311 static void transcode_osd_close( sout_stream_t *p_stream, sout_stream_id_t *id)
2313 sout_stream_sys_t *p_sys = p_stream->p_sys;
2318 if( id->p_encoder->p_module )
2319 module_unneed( id->p_encoder, id->p_encoder->p_module );
2321 p_sys->b_osd = false;
2324 static int transcode_osd_process( sout_stream_t *p_stream,
2325 sout_stream_id_t *id,
2326 block_t *in, block_t **out )
2328 sout_stream_sys_t *p_sys = p_stream->p_sys;
2329 subpicture_t *p_subpic = NULL;
2331 /* Check if we have a subpicture to send */
2332 if( p_sys->p_spu && in->i_dts > 0)
2334 p_subpic = spu_SortSubpictures( p_sys->p_spu, in->i_dts, false );
2338 msg_Warn( p_stream, "spu channel not initialized, doing it now" );
2341 p_sys->p_spu = spu_Create( p_stream );
2342 spu_Init( p_sys->p_spu );
2348 block_t *p_block = NULL;
2350 if( p_sys->b_master_sync && p_sys->i_master_drift )
2352 p_subpic->i_start -= p_sys->i_master_drift;
2353 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2356 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2357 subpicture_Delete( p_subpic );
2360 p_block->i_dts = p_block->i_pts = in->i_dts;
2361 block_ChainAppend( out, p_block );
2365 return VLC_EGENERIC;