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"
36 static const int pi_channels_maps
[6] =
39 AOUT_CHAN_CENTER
, AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
,
40 AOUT_CHAN_CENTER
| AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
,
41 AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_REARLEFT
42 | AOUT_CHAN_REARRIGHT
,
43 AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_CENTER
44 | AOUT_CHAN_REARLEFT
| AOUT_CHAN_REARRIGHT
47 static inline void audio_timer_start( encoder_t
* p_encoder
)
49 stats_TimerStart( p_encoder
, "encoding audio frame",
50 STATS_TIMER_AUDIO_FRAME_ENCODING
);
53 static inline void audio_timer_stop( encoder_t
* p_encoder
)
55 stats_TimerStop( p_encoder
, STATS_TIMER_AUDIO_FRAME_ENCODING
);
58 static inline void audio_timer_close( encoder_t
* p_encoder
)
60 stats_TimerDump( p_encoder
, STATS_TIMER_AUDIO_FRAME_ENCODING
);
61 stats_TimerClean( p_encoder
, STATS_TIMER_AUDIO_FRAME_ENCODING
);
64 static block_t
*transcode_audio_alloc( filter_t
*p_filter
, int size
)
66 VLC_UNUSED( p_filter
);
67 return block_Alloc( size
);
70 static aout_buffer_t
*audio_new_buffer( decoder_t
*p_dec
, int i_samples
)
75 if( p_dec
->fmt_out
.audio
.i_bitspersample
)
77 i_size
= i_samples
* p_dec
->fmt_out
.audio
.i_bitspersample
/ 8 *
78 p_dec
->fmt_out
.audio
.i_channels
;
80 else if( p_dec
->fmt_out
.audio
.i_bytes_per_frame
&&
81 p_dec
->fmt_out
.audio
.i_frame_length
)
83 i_size
= i_samples
* p_dec
->fmt_out
.audio
.i_bytes_per_frame
/
84 p_dec
->fmt_out
.audio
.i_frame_length
;
88 i_size
= i_samples
* 4 * p_dec
->fmt_out
.audio
.i_channels
;
91 p_block
= block_New( p_dec
, i_size
);
92 p_block
->i_nb_samples
= i_samples
;
96 static void audio_del_buffer( decoder_t
*p_dec
, aout_buffer_t
*p_buffer
)
99 block_Release( p_buffer
);
102 static int transcode_audio_filter_allocation_init( filter_t
*p_filter
,
106 p_filter
->pf_audio_buffer_new
= transcode_audio_alloc
;
110 static bool transcode_audio_filter_needed( const es_format_t
*p_fmt1
, const es_format_t
*p_fmt2
)
112 if( p_fmt1
->i_codec
!= p_fmt2
->i_codec
||
113 p_fmt1
->audio
.i_channels
!= p_fmt2
->audio
.i_channels
||
114 p_fmt1
->audio
.i_rate
!= p_fmt2
->audio
.i_rate
)
118 static int transcode_audio_filter_chain_build( sout_stream_t
*p_stream
, filter_chain_t
*p_chain
,
119 const es_format_t
*p_dst
, const es_format_t
*p_src
)
121 if( !transcode_audio_filter_needed( p_dst
, p_src
) )
124 es_format_t current
= *p_src
;
126 msg_Dbg( p_stream
, "Looking for filter "
127 "(%4.4s->%4.4s, channels %d->%d, rate %d->%d)",
128 (const char *)&p_src
->i_codec
,
129 (const char *)&p_dst
->i_codec
,
130 p_src
->audio
.i_channels
,
131 p_dst
->audio
.i_channels
,
133 p_dst
->audio
.i_rate
);
135 /* If any filter is needed, convert to fl32 */
136 if( current
.i_codec
!= VLC_CODEC_FL32
)
138 /* First step, convert to fl32 */
140 current
.audio
.i_format
= VLC_CODEC_FL32
;
141 aout_FormatPrepare( ¤t
.audio
);
143 if( !filter_chain_AppendFilter( p_chain
, NULL
, NULL
, NULL
, ¤t
) )
145 msg_Err( p_stream
, "Failed to find conversion filter to fl32" );
148 current
= *filter_chain_GetFmtOut( p_chain
);
151 /* Fix sample rate */
152 if( current
.audio
.i_rate
!= p_dst
->audio
.i_rate
)
154 current
.audio
.i_rate
= p_dst
->audio
.i_rate
;
155 aout_FormatPrepare( ¤t
.audio
);
156 if( !filter_chain_AppendFilter( p_chain
, NULL
, NULL
, NULL
, ¤t
) )
158 msg_Err( p_stream
, "Failed to find conversion filter for resampling" );
161 current
= *filter_chain_GetFmtOut( p_chain
);
165 if( current
.audio
.i_channels
!= p_dst
->audio
.i_channels
)
167 current
.audio
.i_channels
= p_dst
->audio
.i_channels
;
168 current
.audio
.i_physical_channels
= p_dst
->audio
.i_physical_channels
;
169 current
.audio
.i_original_channels
= p_dst
->audio
.i_original_channels
;
171 if( ( !current
.audio
.i_physical_channels
|| !current
.audio
.i_original_channels
) &&
172 current
.audio
.i_channels
< 6 )
173 current
.audio
.i_physical_channels
=
174 current
.audio
.i_original_channels
= pi_channels_maps
[current
.audio
.i_channels
];
176 aout_FormatPrepare( ¤t
.audio
);
177 if( !filter_chain_AppendFilter( p_chain
, NULL
, NULL
, NULL
, ¤t
) )
179 msg_Err( p_stream
, "Failed to find conversion filter for channel mixing" );
182 current
= *filter_chain_GetFmtOut( p_chain
);
184 /* And last step, convert to the requested codec */
185 if( current
.i_codec
!= p_dst
->i_codec
)
187 current
.i_codec
= p_dst
->i_codec
;
188 aout_FormatPrepare( ¤t
.audio
);
189 if( !filter_chain_AppendFilter( p_chain
, NULL
, NULL
, NULL
, ¤t
) )
191 msg_Err( p_stream
, "Failed to find conversion filter to %4.4s",
192 (const char*)&p_dst
->i_codec
);
195 current
= *filter_chain_GetFmtOut( p_chain
);
198 if( transcode_audio_filter_needed( p_dst
, ¤t
) )
200 /* Weird case, a filter has side effects, doomed */
201 msg_Err( p_stream
, "Failed to create a valid audio filter chain" );
205 msg_Dbg( p_stream
, "Got complete audio filter chain" );
210 int transcode_audio_new( sout_stream_t
*p_stream
,
211 sout_stream_id_t
*id
)
213 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
214 es_format_t fmt_last
;
220 /* Initialization of decoder structures */
221 id
->p_decoder
->fmt_out
= id
->p_decoder
->fmt_in
;
222 id
->p_decoder
->fmt_out
.i_extra
= 0;
223 id
->p_decoder
->fmt_out
.p_extra
= 0;
224 id
->p_decoder
->pf_decode_audio
= NULL
;
225 id
->p_decoder
->pf_aout_buffer_new
= audio_new_buffer
;
226 id
->p_decoder
->pf_aout_buffer_del
= audio_del_buffer
;
227 /* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */
229 id
->p_decoder
->p_module
=
230 module_need( id
->p_decoder
, "decoder", "$codec", false );
231 if( !id
->p_decoder
->p_module
)
233 msg_Err( p_stream
, "cannot find audio decoder" );
236 id
->p_decoder
->fmt_out
.audio
.i_bitspersample
=
237 aout_BitsPerSample( id
->p_decoder
->fmt_out
.i_codec
);
238 fmt_last
= id
->p_decoder
->fmt_out
;
239 /* Fix AAC SBR changing number of channels and sampling rate */
240 if( !(id
->p_decoder
->fmt_in
.i_codec
== VLC_CODEC_MP4A
&&
241 fmt_last
.audio
.i_rate
!= id
->p_encoder
->fmt_in
.audio
.i_rate
&&
242 fmt_last
.audio
.i_channels
!= id
->p_encoder
->fmt_in
.audio
.i_channels
) )
243 fmt_last
.audio
.i_rate
= id
->p_decoder
->fmt_in
.audio
.i_rate
;
249 /* Initialization of encoder format structures */
250 es_format_Init( &id
->p_encoder
->fmt_in
, id
->p_decoder
->fmt_in
.i_cat
,
251 id
->p_decoder
->fmt_out
.i_codec
);
252 id
->p_encoder
->fmt_in
.audio
.i_format
= id
->p_decoder
->fmt_out
.i_codec
;
254 id
->p_encoder
->fmt_in
.audio
.i_rate
= id
->p_encoder
->fmt_out
.audio
.i_rate
;
255 id
->p_encoder
->fmt_in
.audio
.i_physical_channels
=
256 id
->p_encoder
->fmt_out
.audio
.i_physical_channels
;
257 id
->p_encoder
->fmt_in
.audio
.i_original_channels
=
258 id
->p_encoder
->fmt_out
.audio
.i_original_channels
;
259 id
->p_encoder
->fmt_in
.audio
.i_channels
=
260 id
->p_encoder
->fmt_out
.audio
.i_channels
;
261 id
->p_encoder
->fmt_in
.audio
.i_bitspersample
=
262 aout_BitsPerSample( id
->p_encoder
->fmt_in
.i_codec
);
264 id
->p_encoder
->p_cfg
= p_stream
->p_sys
->p_audio_cfg
;
265 id
->p_encoder
->p_module
=
266 module_need( id
->p_encoder
, "encoder", p_sys
->psz_aenc
, true );
267 if( !id
->p_encoder
->p_module
)
269 msg_Err( p_stream
, "cannot find audio encoder (module:%s fourcc:%4.4s)",
270 p_sys
->psz_aenc
? p_sys
->psz_aenc
: "any",
271 (char *)&p_sys
->i_acodec
);
272 module_unneed( id
->p_decoder
, id
->p_decoder
->p_module
);
273 id
->p_decoder
->p_module
= NULL
;
276 id
->p_encoder
->fmt_in
.audio
.i_format
= id
->p_encoder
->fmt_in
.i_codec
;
277 id
->p_encoder
->fmt_in
.audio
.i_bitspersample
=
278 aout_BitsPerSample( id
->p_encoder
->fmt_in
.i_codec
);
280 /* Load user specified audio filters */
283 es_format_t fmt_fl32
= fmt_last
;
285 fmt_fl32
.audio
.i_format
= VLC_CODEC_FL32
;
286 if( transcode_audio_filter_chain_build( p_stream
, id
->p_uf_chain
,
287 &fmt_fl32
, &fmt_last
) )
289 transcode_audio_close( id
);
294 id
->p_uf_chain
= filter_chain_New( p_stream
, "audio filter", false,
295 transcode_audio_filter_allocation_init
, NULL
, NULL
);
296 filter_chain_Reset( id
->p_uf_chain
, &fmt_last
, &fmt_fl32
);
297 if( filter_chain_AppendFromString( id
->p_uf_chain
, p_sys
->psz_af
) > 0 )
298 fmt_last
= *filter_chain_GetFmtOut( id
->p_uf_chain
);
301 /* Load conversion filters */
302 id
->p_f_chain
= filter_chain_New( p_stream
, "audio filter", true,
303 transcode_audio_filter_allocation_init
, NULL
, NULL
);
304 filter_chain_Reset( id
->p_f_chain
, &fmt_last
, &id
->p_encoder
->fmt_in
);
306 if( transcode_audio_filter_chain_build( p_stream
, id
->p_f_chain
,
307 &id
->p_encoder
->fmt_in
, &fmt_last
) )
309 transcode_audio_close( id
);
312 fmt_last
= id
->p_encoder
->fmt_in
;
315 id
->p_encoder
->fmt_out
.i_codec
=
316 vlc_fourcc_GetCodec( AUDIO_ES
, id
->p_encoder
->fmt_out
.i_codec
);
321 void transcode_audio_close( sout_stream_id_t
*id
)
323 audio_timer_close( id
->p_encoder
);
326 if( id
->p_decoder
->p_module
)
327 module_unneed( id
->p_decoder
, id
->p_decoder
->p_module
);
328 id
->p_decoder
->p_module
= NULL
;
330 if( id
->p_decoder
->p_description
)
331 vlc_meta_Delete( id
->p_decoder
->p_description
);
332 id
->p_decoder
->p_description
= NULL
;
335 if( id
->p_encoder
->p_module
)
336 module_unneed( id
->p_encoder
, id
->p_encoder
->p_module
);
337 id
->p_encoder
->p_module
= NULL
;
341 filter_chain_Delete( id
->p_uf_chain
);
343 filter_chain_Delete( id
->p_f_chain
);
346 int transcode_audio_process( sout_stream_t
*p_stream
,
347 sout_stream_id_t
*id
,
348 block_t
*in
, block_t
**out
)
350 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
351 block_t
*p_block
, *p_audio_buf
;
354 while( (p_audio_buf
= id
->p_decoder
->pf_decode_audio( id
->p_decoder
,
357 sout_UpdateStatistic( p_stream
->p_sout
, SOUT_STATISTIC_DECODED_AUDIO
, 1 );
358 if( p_sys
->b_master_sync
)
360 mtime_t i_dts
= date_Get( &id
->interpolated_pts
) + 1;
361 if ( p_audio_buf
->i_pts
- i_dts
> MASTER_SYNC_MAX_DRIFT
362 || p_audio_buf
->i_pts
- i_dts
< -MASTER_SYNC_MAX_DRIFT
)
364 msg_Dbg( p_stream
, "drift is too high, resetting master sync" );
365 date_Set( &id
->interpolated_pts
, p_audio_buf
->i_pts
);
366 i_dts
= p_audio_buf
->i_pts
+ 1;
368 p_sys
->i_master_drift
= p_audio_buf
->i_pts
- i_dts
;
369 date_Increment( &id
->interpolated_pts
, p_audio_buf
->i_nb_samples
);
370 p_audio_buf
->i_pts
-= p_sys
->i_master_drift
;
373 p_audio_buf
->i_dts
= p_audio_buf
->i_pts
;
375 /* Run filter chain */
378 p_audio_buf
= filter_chain_AudioFilter( id
->p_uf_chain
,
384 p_audio_buf
= filter_chain_AudioFilter( id
->p_f_chain
, p_audio_buf
);
388 p_audio_buf
->i_dts
= p_audio_buf
->i_pts
;
390 audio_timer_start( id
->p_encoder
);
391 p_block
= id
->p_encoder
->pf_encode_audio( id
->p_encoder
, p_audio_buf
);
392 audio_timer_stop( id
->p_encoder
);
394 block_ChainAppend( out
, p_block
);
395 block_Release( p_audio_buf
);
401 bool transcode_audio_add( sout_stream_t
*p_stream
, es_format_t
*p_fmt
,
402 sout_stream_id_t
*id
)
404 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
407 "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
408 (char*)&p_fmt
->i_codec
, (char*)&p_sys
->i_acodec
);
410 /* Complete destination format */
411 id
->p_encoder
->fmt_out
.i_codec
= p_sys
->i_acodec
;
412 id
->p_encoder
->fmt_out
.audio
.i_rate
= p_sys
->i_sample_rate
> 0 ?
413 p_sys
->i_sample_rate
: p_fmt
->audio
.i_rate
;
414 id
->p_encoder
->fmt_out
.i_bitrate
= p_sys
->i_abitrate
;
415 id
->p_encoder
->fmt_out
.audio
.i_bitspersample
=
416 p_fmt
->audio
.i_bitspersample
;
417 id
->p_encoder
->fmt_out
.audio
.i_channels
= p_sys
->i_channels
> 0 ?
418 p_sys
->i_channels
: p_fmt
->audio
.i_channels
;
419 /* Sanity check for audio channels */
420 id
->p_encoder
->fmt_out
.audio
.i_channels
=
421 __MIN( id
->p_encoder
->fmt_out
.audio
.i_channels
,
422 id
->p_decoder
->fmt_in
.audio
.i_channels
);
423 id
->p_encoder
->fmt_out
.audio
.i_original_channels
=
424 id
->p_decoder
->fmt_in
.audio
.i_physical_channels
;
425 if( id
->p_decoder
->fmt_in
.audio
.i_channels
==
426 id
->p_encoder
->fmt_out
.audio
.i_channels
)
428 id
->p_encoder
->fmt_out
.audio
.i_physical_channels
=
429 id
->p_decoder
->fmt_in
.audio
.i_physical_channels
;
433 id
->p_encoder
->fmt_out
.audio
.i_physical_channels
=
434 pi_channels_maps
[id
->p_encoder
->fmt_out
.audio
.i_channels
];
437 /* Build decoder -> filter -> encoder chain */
438 if( transcode_audio_new( p_stream
, id
) )
440 msg_Err( p_stream
, "cannot create audio chain" );
444 /* Open output stream */
445 id
->id
= sout_StreamIdAdd( p_stream
->p_next
, &id
->p_encoder
->fmt_out
);
446 id
->b_transcode
= true;
450 transcode_audio_close( id
);
454 date_Init( &id
->interpolated_pts
, p_fmt
->audio
.i_rate
, 1 );