1 /*****************************************************************************
2 * audio.c: transcoding stream output module (audio)
3 *****************************************************************************
4 * Copyright (C) 2003-2009 VLC authors and VideoLAN
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 it
13 * under the terms of the GNU Lesser General Public License as published by
14 * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public License
23 * along with this program; if not, write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25 *****************************************************************************/
27 /*****************************************************************************
29 *****************************************************************************/
31 #include "transcode.h"
34 #include <vlc_input.h>
36 #include <vlc_modules.h>
38 static const int pi_channels_maps
[9] =
42 AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
,
43 AOUT_CHAN_LFE
| AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
,
44 AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_REARLEFT
45 | AOUT_CHAN_REARRIGHT
,
46 AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_CENTER
47 | AOUT_CHAN_REARLEFT
| AOUT_CHAN_REARRIGHT
,
48 AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_CENTER
49 | AOUT_CHAN_REARLEFT
| AOUT_CHAN_REARRIGHT
| AOUT_CHAN_LFE
,
50 AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_CENTER
51 | AOUT_CHAN_REARCENTER
| AOUT_CHAN_MIDDLELEFT
52 | AOUT_CHAN_MIDDLERIGHT
| AOUT_CHAN_LFE
,
53 AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_CENTER
| AOUT_CHAN_REARLEFT
54 | AOUT_CHAN_REARRIGHT
| AOUT_CHAN_MIDDLELEFT
| AOUT_CHAN_MIDDLERIGHT
58 static int audio_update_format( decoder_t
*p_dec
)
60 sout_stream_id_sys_t
*id
= p_dec
->p_queue_ctx
;
62 p_dec
->fmt_out
.audio
.i_format
= p_dec
->fmt_out
.i_codec
;
63 aout_FormatPrepare( &p_dec
->fmt_out
.audio
);
65 vlc_mutex_lock(&id
->fifo
.lock
);
66 id
->audio_dec_out
= p_dec
->fmt_out
.audio
;
67 vlc_mutex_unlock(&id
->fifo
.lock
);
69 return ( p_dec
->fmt_out
.audio
.i_bitspersample
> 0 ) ? 0 : -1;
72 static int transcode_audio_initialize_filters( sout_stream_t
*p_stream
, sout_stream_id_sys_t
*id
,
73 sout_stream_sys_t
*p_sys
)
75 /* Load user specified audio filters */
76 /* XXX: These variable names come kinda out of nowhere... */
77 var_Create( p_stream
, "audio-time-stretch", VLC_VAR_BOOL
);
78 var_Create( p_stream
, "audio-filter", VLC_VAR_STRING
);
80 var_SetString( p_stream
, "audio-filter", p_sys
->psz_af
);
81 id
->p_af_chain
= aout_FiltersNew( p_stream
, &id
->audio_dec_out
,
82 &id
->p_encoder
->fmt_in
.audio
, NULL
, NULL
);
83 var_Destroy( p_stream
, "audio-filter" );
84 var_Destroy( p_stream
, "audio-time-stretch" );
85 if( id
->p_af_chain
== NULL
)
87 msg_Err( p_stream
, "Unable to initialize audio filters" );
88 module_unneed( id
->p_encoder
, id
->p_encoder
->p_module
);
89 id
->p_encoder
->p_module
= NULL
;
90 module_unneed( id
->p_decoder
, id
->p_decoder
->p_module
);
91 id
->p_decoder
->p_module
= NULL
;
94 id
->fmt_audio
.i_rate
= id
->audio_dec_out
.i_rate
;
95 id
->fmt_audio
.i_physical_channels
= id
->audio_dec_out
.i_physical_channels
;
99 static int transcode_audio_initialize_encoder( sout_stream_id_sys_t
*id
, sout_stream_t
*p_stream
)
101 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
103 /* Complete destination format */
104 id
->p_encoder
->fmt_out
.i_codec
= p_sys
->i_acodec
;
105 id
->p_encoder
->fmt_out
.audio
.i_rate
= p_sys
->i_sample_rate
> 0 ?
106 p_sys
->i_sample_rate
: id
->audio_dec_out
.i_rate
;
107 id
->p_encoder
->fmt_out
.i_bitrate
= p_sys
->i_abitrate
;
108 id
->p_encoder
->fmt_out
.audio
.i_bitspersample
= id
->audio_dec_out
.i_bitspersample
;
109 id
->p_encoder
->fmt_out
.audio
.i_channels
= p_sys
->i_channels
> 0 ?
110 p_sys
->i_channels
: id
->audio_dec_out
.i_channels
;
111 assert(id
->p_encoder
->fmt_out
.audio
.i_channels
> 0);
112 if( id
->p_encoder
->fmt_out
.audio
.i_channels
>= ARRAY_SIZE(pi_channels_maps
) )
113 id
->p_encoder
->fmt_out
.audio
.i_channels
= ARRAY_SIZE(pi_channels_maps
) - 1;
115 id
->p_encoder
->fmt_in
.audio
.i_physical_channels
=
116 id
->p_encoder
->fmt_out
.audio
.i_physical_channels
=
117 pi_channels_maps
[id
->p_encoder
->fmt_out
.audio
.i_channels
];
119 /* Initialization of encoder format structures */
120 es_format_Init( &id
->p_encoder
->fmt_in
, id
->p_decoder
->fmt_in
.i_cat
,
121 id
->audio_dec_out
.i_format
);
122 id
->p_encoder
->fmt_in
.audio
.i_format
= id
->audio_dec_out
.i_format
;
123 id
->p_encoder
->fmt_in
.audio
.i_rate
= id
->p_encoder
->fmt_out
.audio
.i_rate
;
124 id
->p_encoder
->fmt_in
.audio
.i_physical_channels
=
125 id
->p_encoder
->fmt_out
.audio
.i_physical_channels
;
126 aout_FormatPrepare( &id
->p_encoder
->fmt_in
.audio
);
128 id
->p_encoder
->p_cfg
= p_stream
->p_sys
->p_audio_cfg
;
129 id
->p_encoder
->p_module
=
130 module_need( id
->p_encoder
, "encoder", p_sys
->psz_aenc
, true );
131 /* p_sys->i_acodec = 0 if there isn't acodec defined */
132 if( !id
->p_encoder
->p_module
&& p_sys
->i_acodec
)
134 msg_Err( p_stream
, "cannot find audio encoder (module:%s fourcc:%4.4s). "
135 "Take a look few lines earlier to see possible reason.",
136 p_sys
->psz_aenc
? p_sys
->psz_aenc
: "any",
137 (char *)&p_sys
->i_acodec
);
138 module_unneed( id
->p_decoder
, id
->p_decoder
->p_module
);
139 id
->p_decoder
->p_module
= NULL
;
143 id
->p_encoder
->fmt_out
.i_codec
=
144 vlc_fourcc_GetCodec( AUDIO_ES
, id
->p_encoder
->fmt_out
.i_codec
);
146 /* Fix input format */
147 id
->p_encoder
->fmt_in
.audio
.i_format
= id
->p_encoder
->fmt_in
.i_codec
;
148 if( !id
->p_encoder
->fmt_in
.audio
.i_physical_channels
)
150 if( id
->p_encoder
->fmt_in
.audio
.i_channels
< (sizeof(pi_channels_maps
) / sizeof(*pi_channels_maps
)) )
151 id
->p_encoder
->fmt_in
.audio
.i_physical_channels
=
152 pi_channels_maps
[id
->p_encoder
->fmt_in
.audio
.i_channels
];
154 aout_FormatPrepare( &id
->p_encoder
->fmt_in
.audio
);
159 static int decoder_queue_audio( decoder_t
*p_dec
, block_t
*p_audio
)
161 sout_stream_id_sys_t
*id
= p_dec
->p_queue_ctx
;
163 vlc_mutex_lock(&id
->fifo
.lock
);
164 *id
->fifo
.audio
.last
= p_audio
;
165 id
->fifo
.audio
.last
= &p_audio
->p_next
;
166 vlc_mutex_unlock(&id
->fifo
.lock
);
170 static block_t
*transcode_dequeue_all_audios( sout_stream_id_sys_t
*id
)
172 vlc_mutex_lock(&id
->fifo
.lock
);
173 block_t
*p_audio_bufs
= id
->fifo
.audio
.first
;
174 id
->fifo
.audio
.first
= NULL
;
175 id
->fifo
.audio
.last
= &id
->fifo
.audio
.first
;
176 vlc_mutex_unlock(&id
->fifo
.lock
);
181 static int transcode_audio_new( sout_stream_t
*p_stream
,
182 sout_stream_id_sys_t
*id
)
184 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
190 /* Initialization of decoder structures */
191 id
->p_decoder
->pf_decode
= NULL
;
192 id
->p_decoder
->pf_queue_audio
= decoder_queue_audio
;
193 id
->p_decoder
->p_queue_ctx
= id
;
194 id
->p_decoder
->pf_aout_format_update
= audio_update_format
;
195 /* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */
196 id
->p_decoder
->p_module
=
197 module_need_var( id
->p_decoder
, "audio decoder", "codec" );
198 if( !id
->p_decoder
->p_module
)
200 msg_Err( p_stream
, "cannot find audio decoder" );
204 vlc_mutex_lock(&id
->fifo
.lock
);
205 /* The decoder fmt_out can be uninitialized here (since it can initialized
206 * asynchronously). Fix audio_dec_out with default values in that case.
207 * This should be enough to initialize the encoder for the first time (it
208 * will be reloaded when all informations from the decoder are available).
210 id
->audio_dec_out
= id
->p_decoder
->fmt_out
.audio
;
211 id
->audio_dec_out
.i_format
= id
->p_decoder
->fmt_out
.i_codec
;
212 if (id
->audio_dec_out
.i_format
== 0)
213 id
->audio_dec_out
.i_format
= VLC_CODEC_FL32
;
214 if (id
->audio_dec_out
.i_rate
== 0)
216 id
->audio_dec_out
.i_rate
= id
->p_decoder
->fmt_in
.audio
.i_rate
;
217 if (id
->audio_dec_out
.i_rate
== 0)
218 id
->audio_dec_out
.i_rate
= 48000;
220 if (id
->audio_dec_out
.i_physical_channels
== 0)
222 id
->audio_dec_out
.i_physical_channels
= id
->p_decoder
->fmt_in
.audio
.i_physical_channels
;
223 if (id
->audio_dec_out
.i_physical_channels
== 0)
224 id
->audio_dec_out
.i_physical_channels
= AOUT_CHANS_STEREO
;
226 aout_FormatPrepare( &id
->audio_dec_out
);
231 if( transcode_audio_initialize_encoder( id
, p_stream
) == VLC_EGENERIC
)
233 vlc_mutex_unlock(&id
->fifo
.lock
);
237 if( unlikely( transcode_audio_initialize_filters( p_stream
, id
, p_sys
) != VLC_SUCCESS
) )
239 vlc_mutex_unlock(&id
->fifo
.lock
);
242 vlc_mutex_unlock(&id
->fifo
.lock
);
247 void transcode_audio_close( sout_stream_id_sys_t
*id
)
250 if( id
->p_decoder
->p_module
)
251 module_unneed( id
->p_decoder
, id
->p_decoder
->p_module
);
252 id
->p_decoder
->p_module
= NULL
;
254 if( id
->p_decoder
->p_description
)
255 vlc_meta_Delete( id
->p_decoder
->p_description
);
256 id
->p_decoder
->p_description
= NULL
;
259 if( id
->p_encoder
->p_module
)
260 module_unneed( id
->p_encoder
, id
->p_encoder
->p_module
);
261 id
->p_encoder
->p_module
= NULL
;
264 if( id
->p_af_chain
!= NULL
)
265 aout_FiltersDelete( (vlc_object_t
*)NULL
, id
->p_af_chain
);
268 int transcode_audio_process( sout_stream_t
*p_stream
,
269 sout_stream_id_sys_t
*id
,
270 block_t
*in
, block_t
**out
)
272 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
275 int ret
= id
->p_decoder
->pf_decode( id
->p_decoder
, in
);
276 if( ret
!= VLCDEC_SUCCESS
)
279 block_t
*p_audio_bufs
= transcode_dequeue_all_audios( id
);
280 if( p_audio_bufs
== NULL
)
285 block_t
*p_audio_buf
= p_audio_bufs
;
286 p_audio_bufs
= p_audio_bufs
->p_next
;
287 p_audio_buf
->p_next
= NULL
;
291 block_Release( p_audio_buf
);
295 vlc_mutex_lock(&id
->fifo
.lock
);
296 if( unlikely( !id
->p_encoder
->p_module
) )
298 if( transcode_audio_initialize_encoder( id
, p_stream
) )
300 msg_Err( p_stream
, "cannot create audio chain" );
301 vlc_mutex_unlock(&id
->fifo
.lock
);
304 if( unlikely( transcode_audio_initialize_filters( p_stream
, id
, p_sys
) != VLC_SUCCESS
) )
306 vlc_mutex_unlock(&id
->fifo
.lock
);
309 date_Init( &id
->next_input_pts
, id
->audio_dec_out
.i_rate
, 1 );
310 date_Set( &id
->next_input_pts
, p_audio_buf
->i_pts
);
314 id
->id
= sout_StreamIdAdd( p_stream
->p_next
, &id
->p_encoder
->fmt_out
);
317 vlc_mutex_unlock(&id
->fifo
.lock
);
323 /* Check if audio format has changed, and filters need reinit */
324 if( unlikely( ( id
->audio_dec_out
.i_rate
!= id
->fmt_audio
.i_rate
) ||
325 ( id
->audio_dec_out
.i_physical_channels
!= id
->fmt_audio
.i_physical_channels
) ) )
327 msg_Info( p_stream
, "Audio changed, trying to reinitialize filters" );
328 if( id
->p_af_chain
!= NULL
)
329 aout_FiltersDelete( (vlc_object_t
*)NULL
, id
->p_af_chain
);
331 if( transcode_audio_initialize_filters( p_stream
, id
, p_sys
) != VLC_SUCCESS
)
333 vlc_mutex_unlock(&id
->fifo
.lock
);
337 /* Set next_input_pts to run with new samplerate */
338 date_Init( &id
->next_input_pts
, id
->fmt_audio
.i_rate
, 1 );
339 date_Set( &id
->next_input_pts
, p_audio_buf
->i_pts
);
341 vlc_mutex_unlock(&id
->fifo
.lock
);
343 if( p_sys
->b_master_sync
)
345 mtime_t i_pts
= date_Get( &id
->next_input_pts
);
348 if( likely( p_audio_buf
->i_pts
!= VLC_TS_INVALID
) )
349 i_drift
= p_audio_buf
->i_pts
- i_pts
;
351 if ( unlikely(i_drift
> MASTER_SYNC_MAX_DRIFT
352 || i_drift
< -MASTER_SYNC_MAX_DRIFT
) )
355 "audio drift is too high (%"PRId64
"), resetting master sync",
357 date_Set( &id
->next_input_pts
, p_audio_buf
->i_pts
);
358 i_pts
= date_Get( &id
->next_input_pts
);
359 if( likely(p_audio_buf
->i_pts
!= VLC_TS_INVALID
) )
360 i_drift
= p_audio_buf
->i_pts
- i_pts
;
362 p_sys
->i_master_drift
= i_drift
;
363 date_Increment( &id
->next_input_pts
, p_audio_buf
->i_nb_samples
);
366 p_audio_buf
->i_dts
= p_audio_buf
->i_pts
;
368 /* Run filter chain */
369 p_audio_buf
= aout_FiltersPlay( id
->p_af_chain
, p_audio_buf
,
370 INPUT_RATE_DEFAULT
);
374 p_audio_buf
->i_dts
= p_audio_buf
->i_pts
;
376 block_t
*p_block
= id
->p_encoder
->pf_encode_audio( id
->p_encoder
, p_audio_buf
);
378 block_ChainAppend( out
, p_block
);
379 block_Release( p_audio_buf
);
383 block_Release( p_audio_buf
);
385 } while( p_audio_bufs
);
389 if( unlikely( !id
->b_error
&& in
== NULL
) )
391 if( id
->p_encoder
->p_module
)
395 p_block
= id
->p_encoder
->pf_encode_audio(id
->p_encoder
, NULL
);
396 block_ChainAppend( out
, p_block
);
401 return id
->b_error
? VLC_EGENERIC
: VLC_SUCCESS
;
404 bool transcode_audio_add( sout_stream_t
*p_stream
, const es_format_t
*p_fmt
,
405 sout_stream_id_sys_t
*id
)
407 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
410 "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
411 (char*)&p_fmt
->i_codec
, (char*)&p_sys
->i_acodec
);
413 id
->fifo
.audio
.first
= NULL
;
414 id
->fifo
.audio
.last
= &id
->fifo
.audio
.first
;
416 /* Complete destination format */
417 id
->p_encoder
->fmt_out
.i_codec
= p_sys
->i_acodec
;
418 id
->p_encoder
->fmt_out
.audio
.i_rate
= p_sys
->i_sample_rate
> 0 ?
419 p_sys
->i_sample_rate
: p_fmt
->audio
.i_rate
;
420 id
->p_encoder
->fmt_out
.i_bitrate
= p_sys
->i_abitrate
;
421 id
->p_encoder
->fmt_out
.audio
.i_bitspersample
=
422 p_fmt
->audio
.i_bitspersample
;
423 id
->p_encoder
->fmt_out
.audio
.i_channels
= p_sys
->i_channels
> 0 ?
424 p_sys
->i_channels
: p_fmt
->audio
.i_channels
;
426 if( id
->p_encoder
->fmt_out
.audio
.i_channels
>= ARRAY_SIZE(pi_channels_maps
) )
427 id
->p_encoder
->fmt_out
.audio
.i_channels
= ARRAY_SIZE(pi_channels_maps
) - 1;
429 id
->p_encoder
->fmt_in
.audio
.i_physical_channels
=
430 id
->p_encoder
->fmt_out
.audio
.i_physical_channels
=
431 pi_channels_maps
[id
->p_encoder
->fmt_out
.audio
.i_channels
];
433 /* Build decoder -> filter -> encoder chain */
434 if( transcode_audio_new( p_stream
, id
) == VLC_EGENERIC
)
436 msg_Err( p_stream
, "cannot create audio chain" );
440 /* Open output stream */
441 id
->b_transcode
= true;
443 /* Reinit encoder again later on, when all information from decoders
445 if( id
->p_encoder
->p_module
)
447 module_unneed( id
->p_encoder
, id
->p_encoder
->p_module
);
448 id
->p_encoder
->p_module
= NULL
;
449 if( id
->p_encoder
->fmt_out
.p_extra
)
451 free( id
->p_encoder
->fmt_out
.p_extra
);
452 id
->p_encoder
->fmt_out
.p_extra
= NULL
;
453 id
->p_encoder
->fmt_out
.i_extra
= 0;
455 if( id
->p_af_chain
!= NULL
)
456 aout_FiltersDelete( (vlc_object_t
*)NULL
, id
->p_af_chain
);
457 id
->p_af_chain
= NULL
;