1 /*****************************************************************************
2 * audio.c: transcoding stream output module (audio)
3 *****************************************************************************
4 * Copyright (C) 2003-2009 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 *****************************************************************************/
31 #include "transcode.h"
35 #include <vlc_modules.h>
37 static const int pi_channels_maps
[6] =
40 AOUT_CHAN_CENTER
, AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
,
41 AOUT_CHAN_CENTER
| AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
,
42 AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_REARLEFT
43 | AOUT_CHAN_REARRIGHT
,
44 AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_CENTER
45 | AOUT_CHAN_REARLEFT
| AOUT_CHAN_REARRIGHT
48 static inline void audio_timer_start( encoder_t
* p_encoder
)
50 stats_TimerStart( p_encoder
, "encoding audio frame",
51 STATS_TIMER_AUDIO_FRAME_ENCODING
);
54 static inline void audio_timer_stop( encoder_t
* p_encoder
)
56 stats_TimerStop( p_encoder
, STATS_TIMER_AUDIO_FRAME_ENCODING
);
59 static inline void audio_timer_close( encoder_t
* p_encoder
)
61 stats_TimerDump( p_encoder
, STATS_TIMER_AUDIO_FRAME_ENCODING
);
62 stats_TimerClean( p_encoder
, STATS_TIMER_AUDIO_FRAME_ENCODING
);
65 static block_t
*transcode_audio_alloc( filter_t
*p_filter
, int size
)
67 VLC_UNUSED( p_filter
);
68 return block_Alloc( size
);
71 static aout_buffer_t
*audio_new_buffer( decoder_t
*p_dec
, int i_samples
)
76 if( p_dec
->fmt_out
.audio
.i_bitspersample
)
78 i_size
= i_samples
* p_dec
->fmt_out
.audio
.i_bitspersample
/ 8 *
79 p_dec
->fmt_out
.audio
.i_channels
;
81 else if( p_dec
->fmt_out
.audio
.i_bytes_per_frame
&&
82 p_dec
->fmt_out
.audio
.i_frame_length
)
84 i_size
= i_samples
* p_dec
->fmt_out
.audio
.i_bytes_per_frame
/
85 p_dec
->fmt_out
.audio
.i_frame_length
;
89 i_size
= i_samples
* 4 * p_dec
->fmt_out
.audio
.i_channels
;
92 p_block
= block_New( p_dec
, i_size
);
93 p_block
->i_nb_samples
= i_samples
;
97 static void audio_del_buffer( decoder_t
*p_dec
, aout_buffer_t
*p_buffer
)
100 block_Release( p_buffer
);
103 static int transcode_audio_filter_allocation_init( filter_t
*p_filter
,
107 p_filter
->pf_audio_buffer_new
= transcode_audio_alloc
;
111 static bool transcode_audio_filter_needed( const es_format_t
*p_fmt1
, const es_format_t
*p_fmt2
)
113 if( p_fmt1
->i_codec
!= p_fmt2
->i_codec
||
114 p_fmt1
->audio
.i_channels
!= p_fmt2
->audio
.i_channels
||
115 p_fmt1
->audio
.i_rate
!= p_fmt2
->audio
.i_rate
)
119 static int transcode_audio_filter_chain_build( sout_stream_t
*p_stream
, filter_chain_t
*p_chain
,
120 const es_format_t
*p_dst
, const es_format_t
*p_src
)
122 if( !transcode_audio_filter_needed( p_dst
, p_src
) )
125 es_format_t current
= *p_src
;
127 msg_Dbg( p_stream
, "Looking for filter "
128 "(%4.4s->%4.4s, channels %d->%d, rate %d->%d)",
129 (const char *)&p_src
->i_codec
,
130 (const char *)&p_dst
->i_codec
,
131 p_src
->audio
.i_channels
,
132 p_dst
->audio
.i_channels
,
134 p_dst
->audio
.i_rate
);
136 /* If any filter is needed, convert to fl32 */
137 if( current
.i_codec
!= VLC_CODEC_FL32
)
139 /* First step, convert to fl32 */
141 current
.audio
.i_format
= VLC_CODEC_FL32
;
142 aout_FormatPrepare( ¤t
.audio
);
144 if( !filter_chain_AppendFilter( p_chain
, NULL
, NULL
, NULL
, ¤t
) )
146 msg_Err( p_stream
, "Failed to find conversion filter to fl32" );
149 current
= *filter_chain_GetFmtOut( p_chain
);
152 /* Fix sample rate */
153 if( current
.audio
.i_rate
!= p_dst
->audio
.i_rate
)
155 current
.audio
.i_rate
= p_dst
->audio
.i_rate
;
156 aout_FormatPrepare( ¤t
.audio
);
157 if( !filter_chain_AppendFilter( p_chain
, NULL
, NULL
, NULL
, ¤t
) )
159 msg_Err( p_stream
, "Failed to find conversion filter for resampling" );
162 current
= *filter_chain_GetFmtOut( p_chain
);
166 if( current
.audio
.i_channels
!= p_dst
->audio
.i_channels
)
168 current
.audio
.i_channels
= p_dst
->audio
.i_channels
;
169 current
.audio
.i_physical_channels
= p_dst
->audio
.i_physical_channels
;
170 current
.audio
.i_original_channels
= p_dst
->audio
.i_original_channels
;
172 if( ( !current
.audio
.i_physical_channels
|| !current
.audio
.i_original_channels
) &&
173 current
.audio
.i_channels
< 6 )
174 current
.audio
.i_physical_channels
=
175 current
.audio
.i_original_channels
= pi_channels_maps
[current
.audio
.i_channels
];
177 aout_FormatPrepare( ¤t
.audio
);
178 if( !filter_chain_AppendFilter( p_chain
, NULL
, NULL
, NULL
, ¤t
) )
180 msg_Err( p_stream
, "Failed to find conversion filter for channel mixing" );
183 current
= *filter_chain_GetFmtOut( p_chain
);
185 /* And last step, convert to the requested codec */
186 if( current
.i_codec
!= p_dst
->i_codec
)
188 current
.i_codec
= p_dst
->i_codec
;
189 aout_FormatPrepare( ¤t
.audio
);
190 if( !filter_chain_AppendFilter( p_chain
, NULL
, NULL
, NULL
, ¤t
) )
192 msg_Err( p_stream
, "Failed to find conversion filter to %4.4s",
193 (const char*)&p_dst
->i_codec
);
196 current
= *filter_chain_GetFmtOut( p_chain
);
199 if( transcode_audio_filter_needed( p_dst
, ¤t
) )
201 /* Weird case, a filter has side effects, doomed */
202 msg_Err( p_stream
, "Failed to create a valid audio filter chain" );
206 msg_Dbg( p_stream
, "Got complete audio filter chain" );
211 int transcode_audio_new( sout_stream_t
*p_stream
,
212 sout_stream_id_t
*id
)
214 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
215 es_format_t fmt_last
;
221 /* Initialization of decoder structures */
222 id
->p_decoder
->fmt_out
= id
->p_decoder
->fmt_in
;
223 id
->p_decoder
->fmt_out
.i_extra
= 0;
224 id
->p_decoder
->fmt_out
.p_extra
= 0;
225 id
->p_decoder
->pf_decode_audio
= NULL
;
226 id
->p_decoder
->pf_aout_buffer_new
= audio_new_buffer
;
227 id
->p_decoder
->pf_aout_buffer_del
= audio_del_buffer
;
228 /* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */
230 id
->p_decoder
->p_module
=
231 module_need( id
->p_decoder
, "decoder", "$codec", false );
232 if( !id
->p_decoder
->p_module
)
234 msg_Err( p_stream
, "cannot find audio decoder" );
237 id
->p_decoder
->fmt_out
.audio
.i_bitspersample
=
238 aout_BitsPerSample( id
->p_decoder
->fmt_out
.i_codec
);
239 fmt_last
= id
->p_decoder
->fmt_out
;
240 /* Fix AAC SBR changing number of channels and sampling rate */
241 if( !(id
->p_decoder
->fmt_in
.i_codec
== VLC_CODEC_MP4A
&&
242 fmt_last
.audio
.i_rate
!= id
->p_encoder
->fmt_in
.audio
.i_rate
&&
243 fmt_last
.audio
.i_channels
!= id
->p_encoder
->fmt_in
.audio
.i_channels
) )
244 fmt_last
.audio
.i_rate
= id
->p_decoder
->fmt_in
.audio
.i_rate
;
250 /* Initialization of encoder format structures */
251 es_format_Init( &id
->p_encoder
->fmt_in
, id
->p_decoder
->fmt_in
.i_cat
,
252 id
->p_decoder
->fmt_out
.i_codec
);
253 id
->p_encoder
->fmt_in
.audio
.i_format
= id
->p_decoder
->fmt_out
.i_codec
;
255 id
->p_encoder
->fmt_in
.audio
.i_rate
= id
->p_encoder
->fmt_out
.audio
.i_rate
;
256 id
->p_encoder
->fmt_in
.audio
.i_physical_channels
=
257 id
->p_encoder
->fmt_out
.audio
.i_physical_channels
;
258 id
->p_encoder
->fmt_in
.audio
.i_original_channels
=
259 id
->p_encoder
->fmt_out
.audio
.i_original_channels
;
260 id
->p_encoder
->fmt_in
.audio
.i_channels
=
261 id
->p_encoder
->fmt_out
.audio
.i_channels
;
262 id
->p_encoder
->fmt_in
.audio
.i_bitspersample
=
263 aout_BitsPerSample( id
->p_encoder
->fmt_in
.i_codec
);
265 id
->p_encoder
->p_cfg
= p_stream
->p_sys
->p_audio_cfg
;
266 id
->p_encoder
->p_module
=
267 module_need( id
->p_encoder
, "encoder", p_sys
->psz_aenc
, true );
268 if( !id
->p_encoder
->p_module
)
270 msg_Err( p_stream
, "cannot find audio encoder (module:%s fourcc:%4.4s). Take a look few lines earlier to see possible reason.",
271 p_sys
->psz_aenc
? p_sys
->psz_aenc
: "any",
272 (char *)&p_sys
->i_acodec
);
273 module_unneed( id
->p_decoder
, id
->p_decoder
->p_module
);
274 id
->p_decoder
->p_module
= NULL
;
277 id
->p_encoder
->fmt_in
.audio
.i_format
= id
->p_encoder
->fmt_in
.i_codec
;
278 id
->p_encoder
->fmt_in
.audio
.i_bitspersample
=
279 aout_BitsPerSample( id
->p_encoder
->fmt_in
.i_codec
);
281 /* Load user specified audio filters */
284 es_format_t fmt_fl32
= fmt_last
;
286 fmt_fl32
.audio
.i_format
= VLC_CODEC_FL32
;
287 if( transcode_audio_filter_chain_build( p_stream
, id
->p_uf_chain
,
288 &fmt_fl32
, &fmt_last
) )
290 transcode_audio_close( id
);
295 id
->p_uf_chain
= filter_chain_New( p_stream
, "audio filter", false,
296 transcode_audio_filter_allocation_init
, NULL
, NULL
);
297 filter_chain_Reset( id
->p_uf_chain
, &fmt_last
, &fmt_fl32
);
298 if( filter_chain_AppendFromString( id
->p_uf_chain
, p_sys
->psz_af
) > 0 )
299 fmt_last
= *filter_chain_GetFmtOut( id
->p_uf_chain
);
302 /* Load conversion filters */
303 id
->p_f_chain
= filter_chain_New( p_stream
, "audio filter", true,
304 transcode_audio_filter_allocation_init
, NULL
, NULL
);
305 filter_chain_Reset( id
->p_f_chain
, &fmt_last
, &id
->p_encoder
->fmt_in
);
307 if( transcode_audio_filter_chain_build( p_stream
, id
->p_f_chain
,
308 &id
->p_encoder
->fmt_in
, &fmt_last
) )
310 transcode_audio_close( id
);
313 fmt_last
= id
->p_encoder
->fmt_in
;
316 id
->p_encoder
->fmt_out
.i_codec
=
317 vlc_fourcc_GetCodec( AUDIO_ES
, id
->p_encoder
->fmt_out
.i_codec
);
322 void transcode_audio_close( sout_stream_id_t
*id
)
324 audio_timer_close( id
->p_encoder
);
327 if( id
->p_decoder
->p_module
)
328 module_unneed( id
->p_decoder
, id
->p_decoder
->p_module
);
329 id
->p_decoder
->p_module
= NULL
;
331 if( id
->p_decoder
->p_description
)
332 vlc_meta_Delete( id
->p_decoder
->p_description
);
333 id
->p_decoder
->p_description
= NULL
;
336 if( id
->p_encoder
->p_module
)
337 module_unneed( id
->p_encoder
, id
->p_encoder
->p_module
);
338 id
->p_encoder
->p_module
= NULL
;
342 filter_chain_Delete( id
->p_uf_chain
);
344 filter_chain_Delete( id
->p_f_chain
);
347 int transcode_audio_process( sout_stream_t
*p_stream
,
348 sout_stream_id_t
*id
,
349 block_t
*in
, block_t
**out
)
351 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
352 block_t
*p_block
, *p_audio_buf
;
355 while( (p_audio_buf
= id
->p_decoder
->pf_decode_audio( id
->p_decoder
,
358 sout_UpdateStatistic( p_stream
->p_sout
, SOUT_STATISTIC_DECODED_AUDIO
, 1 );
359 if( p_sys
->b_master_sync
)
361 mtime_t i_dts
= date_Get( &id
->interpolated_pts
) + 1;
362 if ( p_audio_buf
->i_pts
- i_dts
> MASTER_SYNC_MAX_DRIFT
363 || p_audio_buf
->i_pts
- i_dts
< -MASTER_SYNC_MAX_DRIFT
)
365 msg_Dbg( p_stream
, "drift is too high, resetting master sync" );
366 date_Set( &id
->interpolated_pts
, p_audio_buf
->i_pts
);
367 i_dts
= p_audio_buf
->i_pts
+ 1;
369 p_sys
->i_master_drift
= p_audio_buf
->i_pts
- i_dts
;
370 date_Increment( &id
->interpolated_pts
, p_audio_buf
->i_nb_samples
);
371 p_audio_buf
->i_pts
-= p_sys
->i_master_drift
;
374 p_audio_buf
->i_dts
= p_audio_buf
->i_pts
;
376 /* Run filter chain */
379 p_audio_buf
= filter_chain_AudioFilter( id
->p_uf_chain
,
385 p_audio_buf
= filter_chain_AudioFilter( id
->p_f_chain
, p_audio_buf
);
389 p_audio_buf
->i_dts
= p_audio_buf
->i_pts
;
391 audio_timer_start( id
->p_encoder
);
392 p_block
= id
->p_encoder
->pf_encode_audio( id
->p_encoder
, p_audio_buf
);
393 audio_timer_stop( id
->p_encoder
);
395 block_ChainAppend( out
, p_block
);
396 block_Release( p_audio_buf
);
402 bool transcode_audio_add( sout_stream_t
*p_stream
, es_format_t
*p_fmt
,
403 sout_stream_id_t
*id
)
405 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
408 "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
409 (char*)&p_fmt
->i_codec
, (char*)&p_sys
->i_acodec
);
411 /* Complete destination format */
412 id
->p_encoder
->fmt_out
.i_codec
= p_sys
->i_acodec
;
413 id
->p_encoder
->fmt_out
.audio
.i_rate
= p_sys
->i_sample_rate
> 0 ?
414 p_sys
->i_sample_rate
: p_fmt
->audio
.i_rate
;
415 id
->p_encoder
->fmt_out
.i_bitrate
= p_sys
->i_abitrate
;
416 id
->p_encoder
->fmt_out
.audio
.i_bitspersample
=
417 p_fmt
->audio
.i_bitspersample
;
418 id
->p_encoder
->fmt_out
.audio
.i_channels
= p_sys
->i_channels
> 0 ?
419 p_sys
->i_channels
: p_fmt
->audio
.i_channels
;
420 /* Sanity check for audio channels */
421 id
->p_encoder
->fmt_out
.audio
.i_channels
=
422 __MIN( id
->p_encoder
->fmt_out
.audio
.i_channels
,
423 id
->p_decoder
->fmt_in
.audio
.i_channels
);
424 id
->p_encoder
->fmt_out
.audio
.i_original_channels
=
425 id
->p_decoder
->fmt_in
.audio
.i_physical_channels
;
426 if( id
->p_decoder
->fmt_in
.audio
.i_channels
==
427 id
->p_encoder
->fmt_out
.audio
.i_channels
)
429 id
->p_encoder
->fmt_out
.audio
.i_physical_channels
=
430 id
->p_decoder
->fmt_in
.audio
.i_physical_channels
;
434 id
->p_encoder
->fmt_out
.audio
.i_physical_channels
=
435 pi_channels_maps
[id
->p_encoder
->fmt_out
.audio
.i_channels
];
438 /* Build decoder -> filter -> encoder chain */
439 if( transcode_audio_new( p_stream
, id
) )
441 msg_Err( p_stream
, "cannot create audio chain" );
445 /* Open output stream */
446 id
->id
= sout_StreamIdAdd( p_stream
->p_next
, &id
->p_encoder
->fmt_out
);
447 id
->b_transcode
= true;
451 transcode_audio_close( id
);
455 date_Init( &id
->interpolated_pts
, p_fmt
->audio
.i_rate
, 1 );