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;
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 =
1315 p_audio_block->i_length = p_audio_buf->end_date -
1317 p_audio_block->i_nb_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_nb_samples;
1332 p_audio_buf->i_pts = 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 aout_buffer_t *audio_new_buffer( decoder_t *p_dec, int i_samples )
1349 aout_buffer_t *p_buffer;
1353 if( p_dec->fmt_out.audio.i_bitspersample )
1355 i_size = i_samples * p_dec->fmt_out.audio.i_bitspersample / 8 *
1356 p_dec->fmt_out.audio.i_channels;
1358 else if( p_dec->fmt_out.audio.i_bytes_per_frame &&
1359 p_dec->fmt_out.audio.i_frame_length )
1361 i_size = i_samples * p_dec->fmt_out.audio.i_bytes_per_frame /
1362 p_dec->fmt_out.audio.i_frame_length;
1366 i_size = i_samples * 4 * p_dec->fmt_out.audio.i_channels;
1369 p_buffer = malloc( sizeof(aout_buffer_t) );
1370 if( !p_buffer ) return NULL;
1371 p_buffer->b_discontinuity = false;
1372 p_buffer->p_sys = p_block = block_New( p_dec, i_size );
1374 p_buffer->p_buffer = p_block->p_buffer;
1375 p_buffer->i_size = p_buffer->i_nb_bytes = p_block->i_buffer;
1376 p_buffer->i_nb_samples = i_samples;
1377 p_block->i_nb_samples = i_samples;
1382 static void audio_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
1385 if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
1393 static picture_t *transcode_video_filter_buffer_new( filter_t *p_filter )
1395 p_filter->fmt_out.video.i_chroma = p_filter->fmt_out.i_codec;
1396 return picture_New( p_filter->fmt_out.video.i_chroma,
1397 p_filter->fmt_out.video.i_width,
1398 p_filter->fmt_out.video.i_height,
1399 p_filter->fmt_out.video.i_aspect );
1401 static void transcode_video_filter_buffer_del( filter_t *p_filter, picture_t *p_pic )
1403 VLC_UNUSED(p_filter);
1404 picture_Release( p_pic );
1407 static int transcode_video_filter_allocation_init( filter_t *p_filter,
1411 p_filter->pf_vout_buffer_new = transcode_video_filter_buffer_new;
1412 p_filter->pf_vout_buffer_del = transcode_video_filter_buffer_del;
1416 static void transcode_video_filter_allocation_clear( filter_t *p_filter )
1418 VLC_UNUSED(p_filter);
1421 static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
1423 sout_stream_sys_t *p_sys = p_stream->p_sys;
1426 * Initialization of decoder structures
1428 id->p_decoder->fmt_out = id->p_decoder->fmt_in;
1429 id->p_decoder->fmt_out.i_extra = 0;
1430 id->p_decoder->fmt_out.p_extra = 0;
1431 id->p_decoder->pf_decode_video = NULL;
1432 id->p_decoder->pf_get_cc = NULL;
1433 id->p_decoder->pf_get_cc = 0;
1434 id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
1435 id->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder;
1436 id->p_decoder->pf_picture_link = video_link_picture_decoder;
1437 id->p_decoder->pf_picture_unlink = video_unlink_picture_decoder;
1438 id->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) );
1439 if( !id->p_decoder->p_owner )
1440 return VLC_EGENERIC;
1442 id->p_decoder->p_owner->p_sys = p_sys;
1443 /* id->p_decoder->p_cfg = p_sys->p_video_cfg; */
1445 id->p_decoder->p_module =
1446 module_need( id->p_decoder, "decoder", "$codec", false );
1448 if( !id->p_decoder->p_module )
1450 msg_Err( p_stream, "cannot find video decoder" );
1451 free( id->p_decoder->p_owner );
1452 return VLC_EGENERIC;
1457 * Because some info about the decoded input will only be available
1458 * once the first frame is decoded, we actually only test the availability
1459 * of the encoder here.
1462 /* Initialization of encoder format structures */
1463 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
1464 id->p_decoder->fmt_out.i_codec );
1465 id->p_encoder->fmt_in.video.i_chroma = id->p_decoder->fmt_out.i_codec;
1467 /* The dimensions will be set properly later on.
1468 * Just put sensible values so we can test an encoder is available. */
1469 id->p_encoder->fmt_in.video.i_width =
1470 id->p_encoder->fmt_out.video.i_width
1471 ? id->p_encoder->fmt_out.video.i_width
1472 : id->p_decoder->fmt_in.video.i_width
1473 ? id->p_decoder->fmt_in.video.i_width : 16;
1474 id->p_encoder->fmt_in.video.i_height =
1475 id->p_encoder->fmt_out.video.i_height
1476 ? id->p_encoder->fmt_out.video.i_height
1477 : id->p_decoder->fmt_in.video.i_height
1478 ? id->p_decoder->fmt_in.video.i_height : 16;
1479 id->p_encoder->fmt_in.video.i_frame_rate = ENC_FRAMERATE;
1480 id->p_encoder->fmt_in.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1482 id->p_encoder->i_threads = p_sys->i_threads;
1483 id->p_encoder->p_cfg = p_sys->p_video_cfg;
1485 id->p_encoder->p_module =
1486 module_need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1487 if( !id->p_encoder->p_module )
1489 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1490 p_sys->psz_venc ? p_sys->psz_venc : "any",
1491 (char *)&p_sys->i_vcodec );
1492 module_unneed( id->p_decoder, id->p_decoder->p_module );
1493 id->p_decoder->p_module = 0;
1494 free( id->p_decoder->p_owner );
1495 return VLC_EGENERIC;
1498 /* Close the encoder.
1499 * We'll open it only when we have the first frame. */
1500 module_unneed( id->p_encoder, id->p_encoder->p_module );
1501 if( id->p_encoder->fmt_out.p_extra )
1503 free( id->p_encoder->fmt_out.p_extra );
1504 id->p_encoder->fmt_out.p_extra = NULL;
1505 id->p_encoder->fmt_out.i_extra = 0;
1507 id->p_encoder->p_module = NULL;
1509 if( p_sys->i_threads >= 1 )
1511 int i_priority = p_sys->b_high_priority ? VLC_THREAD_PRIORITY_OUTPUT :
1512 VLC_THREAD_PRIORITY_VIDEO;
1513 p_sys->id_video = id;
1514 vlc_mutex_init( &p_sys->lock_out );
1515 vlc_cond_init( &p_sys->cond );
1516 memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) );
1517 p_sys->i_first_pic = 0;
1518 p_sys->i_last_pic = 0;
1519 p_sys->p_buffers = NULL;
1520 p_sys->b_die = p_sys->b_error = 0;
1521 if( vlc_thread_create( p_sys, "encoder", EncoderThread, i_priority ) )
1523 msg_Err( p_stream, "cannot spawn encoder thread" );
1524 module_unneed( id->p_decoder, id->p_decoder->p_module );
1525 id->p_decoder->p_module = 0;
1526 free( id->p_decoder->p_owner );
1527 return VLC_EGENERIC;
1534 static void transcode_video_encoder_init( sout_stream_t *p_stream,
1535 sout_stream_id_t *id )
1537 sout_stream_sys_t *p_sys = p_stream->p_sys;
1539 /* Calculate scaling
1540 * width/height of source */
1541 int i_src_width = id->p_decoder->fmt_out.video.i_width;
1542 int i_src_height = id->p_decoder->fmt_out.video.i_height;
1544 /* with/height scaling */
1545 float f_scale_width = 1;
1546 float f_scale_height = 1;
1548 /* width/height of output stream */
1553 float f_aspect = (float)id->p_decoder->fmt_out.video.i_aspect /
1556 msg_Dbg( p_stream, "decoder aspect is %i:%i",
1557 id->p_decoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1559 /* Change f_aspect from source frame to source pixel */
1560 f_aspect = f_aspect * i_src_height / i_src_width;
1561 msg_Dbg( p_stream, "source pixel aspect is %f:1", f_aspect );
1563 /* Calculate scaling factor for specified parameters */
1564 if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1565 id->p_encoder->fmt_out.video.i_height <= 0 && p_sys->f_scale )
1567 /* Global scaling. Make sure width will remain a factor of 16 */
1570 int i_new_width = i_src_width * p_sys->f_scale;
1572 if( i_new_width % 16 <= 7 && i_new_width >= 16 )
1573 i_new_width -= i_new_width % 16;
1575 i_new_width += 16 - i_new_width % 16;
1577 f_real_scale = (float)( i_new_width ) / (float) i_src_width;
1579 i_new_height = __MAX( 16, i_src_height * (float)f_real_scale );
1581 f_scale_width = f_real_scale;
1582 f_scale_height = (float) i_new_height / (float) i_src_height;
1584 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1585 id->p_encoder->fmt_out.video.i_height <= 0 )
1587 /* Only width specified */
1588 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1589 f_scale_height = f_scale_width;
1591 else if( id->p_encoder->fmt_out.video.i_width <= 0 &&
1592 id->p_encoder->fmt_out.video.i_height > 0 )
1594 /* Only height specified */
1595 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1596 f_scale_width = f_scale_height;
1598 else if( id->p_encoder->fmt_out.video.i_width > 0 &&
1599 id->p_encoder->fmt_out.video.i_height > 0 )
1601 /* Width and height specified */
1602 f_scale_width = (float)id->p_encoder->fmt_out.video.i_width/i_src_width;
1603 f_scale_height = (float)id->p_encoder->fmt_out.video.i_height/i_src_height;
1606 /* check maxwidth and maxheight
1608 if( p_sys->i_maxwidth && f_scale_width > (float)p_sys->i_maxwidth /
1611 f_scale_width = (float)p_sys->i_maxwidth / i_src_width;
1614 if( p_sys->i_maxheight && f_scale_height > (float)p_sys->i_maxheight /
1617 f_scale_height = (float)p_sys->i_maxheight / i_src_height;
1621 /* Change aspect ratio from source pixel to scaled pixel */
1622 f_aspect = f_aspect * f_scale_height / f_scale_width;
1623 msg_Dbg( p_stream, "scaled pixel aspect is %f:1", f_aspect );
1625 /* f_scale_width and f_scale_height are now final */
1626 /* Calculate width, height from scaling
1627 * Make sure its multiple of 2
1629 i_dst_width = 2 * (int)(f_scale_width*i_src_width/2+0.5);
1630 i_dst_height = 2 * (int)(f_scale_height*i_src_height/2+0.5);
1632 /* Change aspect ratio from scaled pixel to output frame */
1633 f_aspect = f_aspect * i_dst_width / i_dst_height;
1635 /* Store calculated values */
1636 id->p_encoder->fmt_out.video.i_width =
1637 id->p_encoder->fmt_out.video.i_visible_width = i_dst_width;
1638 id->p_encoder->fmt_out.video.i_height =
1639 id->p_encoder->fmt_out.video.i_visible_height = i_dst_height;
1641 id->p_encoder->fmt_in.video.i_width =
1642 id->p_encoder->fmt_in.video.i_visible_width = i_dst_width;
1643 id->p_encoder->fmt_in.video.i_height =
1644 id->p_encoder->fmt_in.video.i_visible_height = i_dst_height;
1646 msg_Dbg( p_stream, "source %ix%i, destination %ix%i",
1647 i_src_width, i_src_height,
1648 i_dst_width, i_dst_height
1651 /* Handle frame rate conversion */
1652 if( !id->p_encoder->fmt_out.video.i_frame_rate ||
1653 !id->p_encoder->fmt_out.video.i_frame_rate_base )
1655 if( id->p_decoder->fmt_out.video.i_frame_rate &&
1656 id->p_decoder->fmt_out.video.i_frame_rate_base )
1658 id->p_encoder->fmt_out.video.i_frame_rate =
1659 id->p_decoder->fmt_out.video.i_frame_rate;
1660 id->p_encoder->fmt_out.video.i_frame_rate_base =
1661 id->p_decoder->fmt_out.video.i_frame_rate_base;
1665 /* Pick a sensible default value */
1666 id->p_encoder->fmt_out.video.i_frame_rate = ENC_FRAMERATE;
1667 id->p_encoder->fmt_out.video.i_frame_rate_base = ENC_FRAMERATE_BASE;
1671 id->p_encoder->fmt_in.video.i_frame_rate =
1672 id->p_encoder->fmt_out.video.i_frame_rate;
1673 id->p_encoder->fmt_in.video.i_frame_rate_base =
1674 id->p_encoder->fmt_out.video.i_frame_rate_base;
1676 date_Init( &id->interpolated_pts,
1677 id->p_encoder->fmt_out.video.i_frame_rate,
1678 id->p_encoder->fmt_out.video.i_frame_rate_base );
1680 /* Check whether a particular aspect ratio was requested */
1681 if( !id->p_encoder->fmt_out.video.i_aspect )
1683 id->p_encoder->fmt_out.video.i_aspect =
1684 (int)( f_aspect * VOUT_ASPECT_FACTOR + 0.5 );
1686 id->p_encoder->fmt_in.video.i_aspect =
1687 id->p_encoder->fmt_out.video.i_aspect;
1689 msg_Dbg( p_stream, "encoder aspect is %i:%i",
1690 id->p_encoder->fmt_out.video.i_aspect, VOUT_ASPECT_FACTOR );
1692 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1695 static int transcode_video_encoder_open( sout_stream_t *p_stream,
1696 sout_stream_id_t *id )
1698 sout_stream_sys_t *p_sys = p_stream->p_sys;
1701 msg_Dbg( p_stream, "destination (after video filters) %ix%i",
1702 id->p_encoder->fmt_in.video.i_width,
1703 id->p_encoder->fmt_in.video.i_height );
1705 id->p_encoder->p_module =
1706 module_need( id->p_encoder, "encoder", p_sys->psz_venc, true );
1707 if( !id->p_encoder->p_module )
1709 msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)",
1710 p_sys->psz_venc ? p_sys->psz_venc : "any",
1711 (char *)&p_sys->i_vcodec );
1712 return VLC_EGENERIC;
1715 id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec;
1718 id->p_encoder->fmt_out.i_codec =
1719 vlc_fourcc_GetCodec( VIDEO_ES, id->p_encoder->fmt_out.i_codec );
1721 id->id = sout_StreamIdAdd( p_stream->p_sys->p_out,
1722 &id->p_encoder->fmt_out );
1725 msg_Err( p_stream, "cannot add this stream" );
1726 return VLC_EGENERIC;
1732 static void transcode_video_close( sout_stream_t *p_stream,
1733 sout_stream_id_t *id )
1735 if( p_stream->p_sys->i_threads >= 1 )
1737 vlc_mutex_lock( &p_stream->p_sys->lock_out );
1738 vlc_object_kill( p_stream->p_sys );
1739 vlc_cond_signal( &p_stream->p_sys->cond );
1740 vlc_mutex_unlock( &p_stream->p_sys->lock_out );
1741 vlc_thread_join( p_stream->p_sys );
1742 vlc_mutex_destroy( &p_stream->p_sys->lock_out );
1743 vlc_cond_destroy( &p_stream->p_sys->cond );
1746 video_timer_close( id->p_encoder );
1749 if( id->p_decoder->p_module )
1750 module_unneed( id->p_decoder, id->p_decoder->p_module );
1751 if( id->p_decoder->p_description )
1752 vlc_meta_Delete( id->p_decoder->p_description );
1754 free( id->p_decoder->p_owner );
1757 if( id->p_encoder->p_module )
1758 module_unneed( id->p_encoder, id->p_encoder->p_module );
1762 filter_chain_Delete( id->p_f_chain );
1763 if( id->p_uf_chain )
1764 filter_chain_Delete( id->p_uf_chain );
1767 static int transcode_video_process( sout_stream_t *p_stream,
1768 sout_stream_id_t *id,
1769 block_t *in, block_t **out )
1771 sout_stream_sys_t *p_sys = p_stream->p_sys;
1772 int i_duplicate = 1;
1773 picture_t *p_pic, *p_pic2 = NULL;
1776 while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
1778 subpicture_t *p_subpic = NULL;
1780 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_VIDEO, 1 );
1782 if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )
1784 mtime_t current_date = mdate();
1785 if( current_date + 50000 > p_pic->date )
1787 msg_Dbg( p_stream, "late picture skipped (%"PRId64")",
1788 current_date + 50000 - p_pic->date );
1789 picture_Release( p_pic );
1794 if( p_sys->b_master_sync )
1796 mtime_t i_video_drift;
1797 mtime_t i_master_drift = p_sys->i_master_drift;
1800 i_pts = date_Get( &id->interpolated_pts ) + 1;
1801 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1802 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
1804 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1805 date_Set( &id->interpolated_pts, p_pic->date );
1806 i_pts = p_pic->date + 1;
1808 i_video_drift = p_pic->date - i_pts;
1811 /* Set the pts of the frame being encoded */
1812 p_pic->date = i_pts;
1814 if( i_video_drift < (i_master_drift - 50000) )
1817 msg_Dbg( p_stream, "dropping frame (%i)",
1818 (int)(i_video_drift - i_master_drift) );
1820 picture_Release( p_pic );
1823 else if( i_video_drift > (i_master_drift + 50000) )
1826 msg_Dbg( p_stream, "adding frame (%i)",
1827 (int)(i_video_drift - i_master_drift) );
1833 if( !id->p_encoder->p_module )
1835 transcode_video_encoder_init( p_stream, id );
1837 id->p_f_chain = filter_chain_New( p_stream, "video filter2",
1839 transcode_video_filter_allocation_init,
1840 transcode_video_filter_allocation_clear,
1844 if( p_stream->p_sys->b_deinterlace )
1846 filter_chain_AppendFilter( id->p_f_chain,
1847 p_sys->psz_deinterlace,
1848 p_sys->p_deinterlace_cfg,
1849 &id->p_decoder->fmt_out,
1850 &id->p_decoder->fmt_out );
1853 /* Take care of the scaling and chroma conversions */
1854 if( ( id->p_decoder->fmt_out.video.i_chroma !=
1855 id->p_encoder->fmt_in.video.i_chroma ) ||
1856 ( id->p_decoder->fmt_out.video.i_width !=
1857 id->p_encoder->fmt_in.video.i_width ) ||
1858 ( id->p_decoder->fmt_out.video.i_height !=
1859 id->p_encoder->fmt_in.video.i_height ) )
1861 filter_chain_AppendFilter( id->p_f_chain,
1863 &id->p_decoder->fmt_out,
1864 &id->p_encoder->fmt_in );
1867 if( p_sys->psz_vf2 )
1869 const es_format_t *p_fmt_out;
1870 id->p_uf_chain = filter_chain_New( p_stream, "video filter2",
1872 transcode_video_filter_allocation_init,
1873 transcode_video_filter_allocation_clear,
1875 filter_chain_Reset( id->p_uf_chain, &id->p_encoder->fmt_in,
1876 &id->p_encoder->fmt_in );
1877 filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_vf2 );
1878 p_fmt_out = filter_chain_GetFmtOut( id->p_uf_chain );
1879 es_format_Copy( &id->p_encoder->fmt_in, p_fmt_out );
1880 id->p_encoder->fmt_out.video.i_width =
1881 id->p_encoder->fmt_in.video.i_width;
1882 id->p_encoder->fmt_out.video.i_height =
1883 id->p_encoder->fmt_in.video.i_height;
1884 id->p_encoder->fmt_out.video.i_aspect =
1885 id->p_encoder->fmt_in.video.i_aspect;
1888 if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS )
1890 picture_Release( p_pic );
1891 transcode_video_close( p_stream, id );
1892 id->b_transcode = false;
1893 return VLC_EGENERIC;
1897 /* Run filter chain */
1899 p_pic = filter_chain_VideoFilter( id->p_f_chain, p_pic );
1905 /* Check if we have a subpicture to overlay */
1908 p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date, false );
1909 /* TODO: get another pic */
1912 /* Overlay subpicture */
1917 if( picture_IsReferenced( p_pic ) && !filter_chain_GetLength( id->p_f_chain ) )
1919 /* We can't modify the picture, we need to duplicate it */
1920 picture_t *p_tmp = video_new_buffer_decoder( id->p_decoder );
1923 picture_Copy( p_tmp, p_pic );
1924 picture_Release( p_pic );
1929 if( filter_chain_GetLength( id->p_f_chain ) > 0 )
1930 fmt = filter_chain_GetFmtOut( id->p_f_chain )->video;
1932 fmt = id->p_decoder->fmt_out.video;
1934 /* FIXME (shouldn't have to be done here) */
1935 fmt.i_sar_num = fmt.i_aspect * fmt.i_height / fmt.i_width;
1936 fmt.i_sar_den = VOUT_ASPECT_FACTOR;
1938 /* FIXME the mdate() seems highly suspicious */
1939 spu_RenderSubpictures( p_sys->p_spu, p_pic, &fmt,
1940 p_subpic, &id->p_decoder->fmt_out.video, mdate() );
1943 /* Run user specified filter chain */
1944 if( id->p_uf_chain )
1945 p_pic = filter_chain_VideoFilter( id->p_uf_chain, p_pic );
1947 if( p_sys->i_threads == 0 )
1951 video_timer_start( id->p_encoder );
1952 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
1953 video_timer_stop( id->p_encoder );
1955 block_ChainAppend( out, p_block );
1958 if( p_sys->b_master_sync )
1960 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
1961 if ( p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT
1962 || p_pic->date - i_pts < -MASTER_SYNC_MAX_DRIFT )
1964 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1965 date_Set( &id->interpolated_pts, p_pic->date );
1966 i_pts = p_pic->date + 1;
1968 date_Increment( &id->interpolated_pts, 1 );
1971 if( p_sys->b_master_sync && i_duplicate > 1 )
1973 mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;
1974 if( (p_pic->date - i_pts > MASTER_SYNC_MAX_DRIFT)
1975 || ((p_pic->date - i_pts) < -MASTER_SYNC_MAX_DRIFT) )
1977 msg_Dbg( p_stream, "drift is too high, resetting master sync" );
1978 date_Set( &id->interpolated_pts, p_pic->date );
1979 i_pts = p_pic->date + 1;
1981 date_Increment( &id->interpolated_pts, 1 );
1983 if( p_sys->i_threads >= 1 )
1985 /* We can't modify the picture, we need to duplicate it */
1986 p_pic2 = video_new_buffer_decoder( id->p_decoder );
1987 if( p_pic2 != NULL )
1989 picture_Copy( p_pic2, p_pic );
1990 p_pic2->date = i_pts;
1996 p_pic->date = i_pts;
1997 video_timer_start( id->p_encoder );
1998 p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);
1999 video_timer_stop( id->p_encoder );
2000 block_ChainAppend( out, p_block );
2004 if( p_sys->i_threads == 0 )
2006 picture_Release( p_pic );
2010 vlc_mutex_lock( &p_sys->lock_out );
2011 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
2012 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2013 *out = p_sys->p_buffers;
2014 p_sys->p_buffers = NULL;
2015 if( p_pic2 != NULL )
2017 p_sys->pp_pics[p_sys->i_last_pic++] = p_pic2;
2018 p_sys->i_last_pic %= PICTURE_RING_SIZE;
2020 vlc_cond_signal( &p_sys->cond );
2021 vlc_mutex_unlock( &p_sys->lock_out );
2028 static void* EncoderThread( vlc_object_t* p_this )
2030 sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_this;
2031 sout_stream_id_t *id = p_sys->id_video;
2033 int canc = vlc_savecancel ();
2035 while( vlc_object_alive (p_sys) && !p_sys->b_error )
2039 vlc_mutex_lock( &p_sys->lock_out );
2040 while( p_sys->i_last_pic == p_sys->i_first_pic )
2042 vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );
2043 if( !vlc_object_alive (p_sys) || p_sys->b_error ) break;
2045 if( !vlc_object_alive (p_sys) || p_sys->b_error )
2047 vlc_mutex_unlock( &p_sys->lock_out );
2051 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2052 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2053 vlc_mutex_unlock( &p_sys->lock_out );
2055 video_timer_start( id->p_encoder );
2056 p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
2057 video_timer_stop( id->p_encoder );
2059 vlc_mutex_lock( &p_sys->lock_out );
2060 block_ChainAppend( &p_sys->p_buffers, p_block );
2062 vlc_mutex_unlock( &p_sys->lock_out );
2063 picture_Release( p_pic );
2066 while( p_sys->i_last_pic != p_sys->i_first_pic )
2068 p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
2069 p_sys->i_first_pic %= PICTURE_RING_SIZE;
2070 picture_Release( p_pic );
2072 block_ChainRelease( p_sys->p_buffers );
2074 vlc_restorecancel (canc);
2078 static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
2080 sout_stream_sys_t *p_ssys = p_dec->p_owner->p_sys;
2081 if( p_ssys->i_threads >= 1 )
2083 int i_first_pic = p_ssys->i_first_pic;
2085 if( p_ssys->i_first_pic != p_ssys->i_last_pic )
2087 /* Encoder still has stuff to encode, wait to clear-up the list */
2088 while( p_ssys->i_first_pic == i_first_pic )
2090 #warning THERE IS A DEFINITELY BUG! LOCKING IS INSUFFICIENT!
2097 p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
2098 return picture_New( p_dec->fmt_out.video.i_chroma,
2099 p_dec->fmt_out.video.i_width,
2100 p_dec->fmt_out.video.i_height,
2101 p_dec->fmt_out.video.i_aspect );
2104 static void video_del_buffer_decoder( decoder_t *p_decoder, picture_t *p_pic )
2106 VLC_UNUSED(p_decoder);
2107 picture_Release( p_pic );
2110 static void video_link_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2113 picture_Hold( p_pic );
2116 static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
2119 picture_Release( p_pic );
2125 static subpicture_t *spu_new_buffer( decoder_t * );
2126 static void spu_del_buffer( decoder_t *, subpicture_t * );
2128 static int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2130 sout_stream_sys_t *p_sys = p_stream->p_sys;
2136 /* Initialization of decoder structures */
2137 id->p_decoder->pf_decode_sub = NULL;
2138 id->p_decoder->pf_spu_buffer_new = spu_new_buffer;
2139 id->p_decoder->pf_spu_buffer_del = spu_del_buffer;
2140 id->p_decoder->p_owner = (decoder_owner_sys_t *)p_stream;
2141 /* id->p_decoder->p_cfg = p_sys->p_spu_cfg; */
2143 id->p_decoder->p_module =
2144 module_need( id->p_decoder, "decoder", "$codec", false );
2146 if( !id->p_decoder->p_module )
2148 msg_Err( p_stream, "cannot find spu decoder" );
2149 return VLC_EGENERIC;
2152 if( !p_sys->b_soverlay )
2155 /* Initialization of encoder format structures */
2156 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2157 id->p_decoder->fmt_in.i_codec );
2159 id->p_encoder->p_cfg = p_sys->p_spu_cfg;
2161 id->p_encoder->p_module =
2162 module_need( id->p_encoder, "encoder", p_sys->psz_senc, true );
2164 if( !id->p_encoder->p_module )
2166 module_unneed( id->p_decoder, id->p_decoder->p_module );
2167 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_senc );
2168 return VLC_EGENERIC;
2174 p_sys->p_spu = spu_Create( p_stream );
2175 spu_Init( p_sys->p_spu );
2181 static void transcode_spu_close( sout_stream_id_t *id)
2184 if( id->p_decoder->p_module )
2185 module_unneed( id->p_decoder, id->p_decoder->p_module );
2186 if( id->p_decoder->p_description )
2187 vlc_meta_Delete( id->p_decoder->p_description );
2190 if( id->p_encoder->p_module )
2191 module_unneed( id->p_encoder, id->p_encoder->p_module );
2194 static int transcode_spu_process( sout_stream_t *p_stream,
2195 sout_stream_id_t *id,
2196 block_t *in, block_t **out )
2198 sout_stream_sys_t *p_sys = p_stream->p_sys;
2199 subpicture_t *p_subpic;
2202 p_subpic = id->p_decoder->pf_decode_sub( id->p_decoder, &in );
2204 return VLC_EGENERIC;
2206 sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_SUBTITLE, 1 );
2208 if( p_sys->b_master_sync && p_sys->i_master_drift )
2210 p_subpic->i_start -= p_sys->i_master_drift;
2211 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2214 if( p_sys->b_soverlay )
2216 spu_DisplaySubpicture( p_sys->p_spu, p_subpic );
2222 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2223 spu_del_buffer( id->p_decoder, p_subpic );
2226 block_ChainAppend( out, p_block );
2231 return VLC_EGENERIC;
2234 static subpicture_t *spu_new_buffer( decoder_t *p_dec )
2236 VLC_UNUSED( p_dec );
2237 return subpicture_New();
2240 static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
2242 VLC_UNUSED( p_dec );
2243 subpicture_Delete( p_subpic );
2249 static int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id )
2251 sout_stream_sys_t *p_sys = p_stream->p_sys;
2253 id->p_decoder->fmt_in.i_cat = SPU_ES;
2254 id->p_encoder->fmt_out.psz_language = strdup( "osd" );
2256 if( p_sys->i_osdcodec != 0 || p_sys->psz_osdenc )
2258 msg_Dbg( p_stream, "creating osdmenu transcoding from fcc=`%4.4s' "
2259 "to fcc=`%4.4s'", (char*)&id->p_encoder->fmt_out.i_codec,
2260 (char*)&p_sys->i_osdcodec );
2262 /* Complete destination format */
2263 id->p_encoder->fmt_out.i_codec = p_sys->i_osdcodec;
2266 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
2268 id->p_encoder->fmt_in.psz_language = strdup( "osd" );
2270 id->p_encoder->p_cfg = p_sys->p_osd_cfg;
2272 id->p_encoder->p_module =
2273 module_need( id->p_encoder, "encoder", p_sys->psz_osdenc, true );
2275 if( !id->p_encoder->p_module )
2277 msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_osdenc );
2281 /* open output stream */
2282 id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_encoder->fmt_out );
2283 id->b_transcode = true;
2285 if( !id->id ) goto error;
2289 msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
2290 (char*)&id->p_decoder->fmt_out.i_codec );
2291 id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_decoder->fmt_out );
2292 id->b_transcode = false;
2294 if( !id->id ) goto error;
2299 p_sys->p_spu = spu_Create( p_stream );
2300 spu_Init( p_sys->p_spu );
2306 msg_Err( p_stream, "starting osd encoding thread failed" );
2307 if( id->p_encoder->p_module )
2308 module_unneed( id->p_encoder, id->p_encoder->p_module );
2309 p_sys->b_osd = false;
2310 return VLC_EGENERIC;
2313 static void transcode_osd_close( sout_stream_t *p_stream, sout_stream_id_t *id)
2315 sout_stream_sys_t *p_sys = p_stream->p_sys;
2320 if( id->p_encoder->p_module )
2321 module_unneed( id->p_encoder, id->p_encoder->p_module );
2323 p_sys->b_osd = false;
2326 static int transcode_osd_process( sout_stream_t *p_stream,
2327 sout_stream_id_t *id,
2328 block_t *in, block_t **out )
2330 sout_stream_sys_t *p_sys = p_stream->p_sys;
2331 subpicture_t *p_subpic = NULL;
2333 /* Check if we have a subpicture to send */
2334 if( p_sys->p_spu && in->i_dts > 0)
2336 p_subpic = spu_SortSubpictures( p_sys->p_spu, in->i_dts, false );
2340 msg_Warn( p_stream, "spu channel not initialized, doing it now" );
2343 p_sys->p_spu = spu_Create( p_stream );
2344 spu_Init( p_sys->p_spu );
2350 block_t *p_block = NULL;
2352 if( p_sys->b_master_sync && p_sys->i_master_drift )
2354 p_subpic->i_start -= p_sys->i_master_drift;
2355 if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
2358 p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
2359 subpicture_Delete( p_subpic );
2362 p_block->i_dts = p_block->i_pts = in->i_dts;
2363 block_ChainAppend( out, p_block );
2367 return VLC_EGENERIC;