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
[6] =
41 AOUT_CHAN_CENTER
, AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
,
42 AOUT_CHAN_CENTER
| AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
,
43 AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_REARLEFT
44 | AOUT_CHAN_REARRIGHT
,
45 AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_CENTER
46 | AOUT_CHAN_REARLEFT
| AOUT_CHAN_REARRIGHT
49 static int audio_update_format( decoder_t
*p_dec
)
51 aout_FormatPrepare( &p_dec
->fmt_out
.audio
);
55 static int transcode_audio_initialize_filters( sout_stream_t
*p_stream
, sout_stream_id_sys_t
*id
,
56 sout_stream_sys_t
*p_sys
, audio_sample_format_t
*fmt_last
)
58 /* Load user specified audio filters */
59 /* XXX: These variable names come kinda out of nowhere... */
60 var_Create( p_stream
, "audio-time-stretch", VLC_VAR_BOOL
);
61 var_Create( p_stream
, "audio-filter", VLC_VAR_STRING
);
63 var_SetString( p_stream
, "audio-filter", p_sys
->psz_af
);
64 id
->p_af_chain
= aout_FiltersNew( p_stream
, fmt_last
,
65 &id
->p_encoder
->fmt_in
.audio
, NULL
);
66 var_Destroy( p_stream
, "audio-filter" );
67 var_Destroy( p_stream
, "audio-time-stretch" );
68 if( id
->p_af_chain
== NULL
)
70 msg_Err( p_stream
, "Unable to initialize audio filters" );
71 module_unneed( id
->p_encoder
, id
->p_encoder
->p_module
);
72 id
->p_encoder
->p_module
= NULL
;
73 module_unneed( id
->p_decoder
, id
->p_decoder
->p_module
);
74 id
->p_decoder
->p_module
= NULL
;
77 p_sys
->fmt_audio
.i_rate
= fmt_last
->i_rate
;
78 p_sys
->fmt_audio
.i_physical_channels
= fmt_last
->i_physical_channels
;
82 static int transcode_audio_initialize_encoder( sout_stream_id_sys_t
*id
, sout_stream_t
*p_stream
)
84 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
85 /* Initialization of encoder format structures */
86 es_format_Init( &id
->p_encoder
->fmt_in
, id
->p_decoder
->fmt_in
.i_cat
,
87 id
->p_decoder
->fmt_out
.i_codec
);
88 id
->p_encoder
->fmt_in
.audio
.i_format
= id
->p_decoder
->fmt_out
.i_codec
;
89 id
->p_encoder
->fmt_in
.audio
.i_rate
= id
->p_encoder
->fmt_out
.audio
.i_rate
;
90 id
->p_encoder
->fmt_in
.audio
.i_physical_channels
=
91 id
->p_encoder
->fmt_out
.audio
.i_physical_channels
;
92 aout_FormatPrepare( &id
->p_encoder
->fmt_in
.audio
);
94 id
->p_encoder
->p_cfg
= p_stream
->p_sys
->p_audio_cfg
;
95 id
->p_encoder
->p_module
=
96 module_need( id
->p_encoder
, "encoder", p_sys
->psz_aenc
, true );
97 /* p_sys->i_acodec = 0 if there isn't acodec defined */
98 if( !id
->p_encoder
->p_module
&& p_sys
->i_acodec
)
100 msg_Err( p_stream
, "cannot find audio encoder (module:%s fourcc:%4.4s). "
101 "Take a look few lines earlier to see possible reason.",
102 p_sys
->psz_aenc
? p_sys
->psz_aenc
: "any",
103 (char *)&p_sys
->i_acodec
);
104 module_unneed( id
->p_decoder
, id
->p_decoder
->p_module
);
105 id
->p_decoder
->p_module
= NULL
;
109 id
->p_encoder
->fmt_out
.i_codec
=
110 vlc_fourcc_GetCodec( AUDIO_ES
, id
->p_encoder
->fmt_out
.i_codec
);
112 /* Fix input format */
113 id
->p_encoder
->fmt_in
.audio
.i_format
= id
->p_encoder
->fmt_in
.i_codec
;
114 if( !id
->p_encoder
->fmt_in
.audio
.i_physical_channels
115 || !id
->p_encoder
->fmt_in
.audio
.i_original_channels
)
117 if( id
->p_encoder
->fmt_in
.audio
.i_channels
< 6 )
118 id
->p_encoder
->fmt_in
.audio
.i_physical_channels
=
119 id
->p_encoder
->fmt_in
.audio
.i_original_channels
=
120 pi_channels_maps
[id
->p_encoder
->fmt_in
.audio
.i_channels
];
122 aout_FormatPrepare( &id
->p_encoder
->fmt_in
.audio
);
127 int transcode_audio_new( sout_stream_t
*p_stream
,
128 sout_stream_id_sys_t
*id
)
130 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
131 audio_sample_format_t fmt_last
;
137 /* Initialization of decoder structures */
138 id
->p_decoder
->fmt_out
= id
->p_decoder
->fmt_in
;
139 id
->p_decoder
->fmt_out
.i_extra
= 0;
140 id
->p_decoder
->fmt_out
.p_extra
= 0;
141 id
->p_decoder
->pf_decode_audio
= NULL
;
142 id
->p_decoder
->pf_aout_format_update
= audio_update_format
;
143 /* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */
144 id
->p_decoder
->p_module
=
145 module_need( id
->p_decoder
, "decoder", "$codec", false );
146 if( !id
->p_decoder
->p_module
)
148 msg_Err( p_stream
, "cannot find audio decoder" );
151 /* decoders don't set audio.i_format, but audio filters use it */
152 id
->p_decoder
->fmt_out
.audio
.i_format
= id
->p_decoder
->fmt_out
.i_codec
;
153 aout_FormatPrepare( &id
->p_decoder
->fmt_out
.audio
);
154 fmt_last
= id
->p_decoder
->fmt_out
.audio
;
155 /* Fix AAC SBR changing number of channels and sampling rate */
156 if( !(id
->p_decoder
->fmt_in
.i_codec
== VLC_CODEC_MP4A
&&
157 fmt_last
.i_rate
!= id
->p_encoder
->fmt_in
.audio
.i_rate
&&
158 fmt_last
.i_channels
!= id
->p_encoder
->fmt_in
.audio
.i_channels
) )
159 fmt_last
.i_rate
= id
->p_decoder
->fmt_in
.audio
.i_rate
;
164 if( transcode_audio_initialize_encoder( id
, p_stream
) == VLC_EGENERIC
)
167 if( unlikely( transcode_audio_initialize_filters( p_stream
, id
, p_sys
,
168 &fmt_last
) != VLC_SUCCESS
) )
174 void transcode_audio_close( sout_stream_id_sys_t
*id
)
177 if( id
->p_decoder
->p_module
)
178 module_unneed( id
->p_decoder
, id
->p_decoder
->p_module
);
179 id
->p_decoder
->p_module
= NULL
;
181 if( id
->p_decoder
->p_description
)
182 vlc_meta_Delete( id
->p_decoder
->p_description
);
183 id
->p_decoder
->p_description
= NULL
;
186 if( id
->p_encoder
->p_module
)
187 module_unneed( id
->p_encoder
, id
->p_encoder
->p_module
);
188 id
->p_encoder
->p_module
= NULL
;
191 if( id
->p_af_chain
!= NULL
)
192 aout_FiltersDelete( (vlc_object_t
*)NULL
, id
->p_af_chain
);
195 int transcode_audio_process( sout_stream_t
*p_stream
,
196 sout_stream_id_sys_t
*id
,
197 block_t
*in
, block_t
**out
)
199 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
200 block_t
*p_block
, *p_audio_buf
;
203 if( unlikely( in
== NULL
) )
207 p_block
= id
->p_encoder
->pf_encode_audio(id
->p_encoder
, NULL
);
208 block_ChainAppend( out
, p_block
);
213 while( (p_audio_buf
= id
->p_decoder
->pf_decode_audio( id
->p_decoder
,
216 if( unlikely( !id
->p_encoder
->p_module
) )
218 /* Complete destination format */
219 id
->p_encoder
->fmt_out
.i_codec
= p_sys
->i_acodec
;
220 id
->p_encoder
->fmt_out
.audio
.i_rate
= p_sys
->i_sample_rate
> 0 ?
221 p_sys
->i_sample_rate
: id
->p_decoder
->fmt_out
.audio
.i_rate
;
222 id
->p_encoder
->fmt_out
.i_bitrate
= p_sys
->i_abitrate
;
223 id
->p_encoder
->fmt_out
.audio
.i_bitspersample
=
224 id
->p_decoder
->fmt_out
.audio
.i_bitspersample
;
225 id
->p_encoder
->fmt_out
.audio
.i_channels
= p_sys
->i_channels
> 0 ?
226 p_sys
->i_channels
: id
->p_decoder
->fmt_out
.audio
.i_channels
;
227 /* Sanity check for audio channels */
228 id
->p_encoder
->fmt_out
.audio
.i_channels
=
229 __MIN( id
->p_encoder
->fmt_out
.audio
.i_channels
,
230 id
->p_decoder
->fmt_out
.audio
.i_channels
);
231 id
->p_encoder
->fmt_out
.audio
.i_original_channels
=
232 id
->p_decoder
->fmt_in
.audio
.i_physical_channels
;
233 id
->p_encoder
->fmt_out
.audio
.i_physical_channels
=
234 pi_channels_maps
[id
->p_encoder
->fmt_out
.audio
.i_channels
];
235 if( transcode_audio_initialize_encoder( id
, p_stream
) )
237 msg_Err( p_stream
, "cannot create audio chain" );
240 if( unlikely( transcode_audio_initialize_filters( p_stream
, id
, p_sys
,
241 &id
->p_decoder
->fmt_out
.audio
) != VLC_SUCCESS
) )
243 date_Init( &id
->interpolated_pts
, id
->p_decoder
->fmt_out
.audio
.i_rate
, 1 );
244 date_Set( &id
->interpolated_pts
, p_audio_buf
->i_pts
);
247 /* Check if audio format has changed, and filters need reinit */
248 if( unlikely( ( id
->p_decoder
->fmt_out
.audio
.i_rate
!= p_sys
->fmt_audio
.i_rate
) ||
249 ( id
->p_decoder
->fmt_out
.audio
.i_physical_channels
!= p_sys
->fmt_audio
.i_physical_channels
) ) )
251 msg_Info( p_stream
, "Audio changed, trying to reinitialize filters" );
252 if( id
->p_af_chain
!= NULL
)
253 aout_FiltersDelete( (vlc_object_t
*)NULL
, id
->p_af_chain
);
255 /* decoders don't set audio.i_format, but audio filters use it */
256 id
->p_decoder
->fmt_out
.audio
.i_format
= id
->p_decoder
->fmt_out
.i_codec
;
257 aout_FormatPrepare( &id
->p_decoder
->fmt_out
.audio
);
259 if( transcode_audio_initialize_filters( p_stream
, id
, p_sys
,
260 &id
->p_decoder
->fmt_out
.audio
) != VLC_SUCCESS
)
263 /* Set interpolated_pts to run with new samplerate */
264 date_Init( &id
->interpolated_pts
, p_sys
->fmt_audio
.i_rate
, 1 );
265 date_Set( &id
->interpolated_pts
, p_audio_buf
->i_pts
);
268 if( p_sys
->b_master_sync
)
270 mtime_t i_pts
= date_Get( &id
->interpolated_pts
);
273 if( likely( p_audio_buf
->i_pts
!= VLC_TS_INVALID
) )
274 i_drift
= p_audio_buf
->i_pts
- i_pts
;
276 if ( unlikely(i_drift
> MASTER_SYNC_MAX_DRIFT
277 || i_drift
< -MASTER_SYNC_MAX_DRIFT
) )
280 "audio drift is too high (%"PRId64
"), resetting master sync",
282 date_Set( &id
->interpolated_pts
, p_audio_buf
->i_pts
);
283 i_pts
= date_Get( &id
->interpolated_pts
);
284 if( likely(p_audio_buf
->i_pts
!= VLC_TS_INVALID
) )
285 i_drift
= p_audio_buf
->i_pts
- i_pts
;
287 p_sys
->i_master_drift
= i_drift
;
288 date_Increment( &id
->interpolated_pts
, p_audio_buf
->i_nb_samples
);
291 p_audio_buf
->i_dts
= p_audio_buf
->i_pts
;
293 /* Run filter chain */
294 p_audio_buf
= aout_FiltersPlay( id
->p_af_chain
, p_audio_buf
,
295 INPUT_RATE_DEFAULT
);
299 p_audio_buf
->i_dts
= p_audio_buf
->i_pts
;
301 p_block
= id
->p_encoder
->pf_encode_audio( id
->p_encoder
, p_audio_buf
);
303 block_ChainAppend( out
, p_block
);
304 block_Release( p_audio_buf
);
310 bool transcode_audio_add( sout_stream_t
*p_stream
, es_format_t
*p_fmt
,
311 sout_stream_id_sys_t
*id
)
313 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
316 "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
317 (char*)&p_fmt
->i_codec
, (char*)&p_sys
->i_acodec
);
319 /* Complete destination format */
320 id
->p_encoder
->fmt_out
.i_codec
= p_sys
->i_acodec
;
321 id
->p_encoder
->fmt_out
.audio
.i_rate
= p_sys
->i_sample_rate
> 0 ?
322 p_sys
->i_sample_rate
: p_fmt
->audio
.i_rate
;
323 id
->p_encoder
->fmt_out
.i_bitrate
= p_sys
->i_abitrate
;
324 id
->p_encoder
->fmt_out
.audio
.i_bitspersample
=
325 p_fmt
->audio
.i_bitspersample
;
326 id
->p_encoder
->fmt_out
.audio
.i_channels
= p_sys
->i_channels
> 0 ?
327 p_sys
->i_channels
: p_fmt
->audio
.i_channels
;
328 /* Sanity check for audio channels */
329 id
->p_encoder
->fmt_out
.audio
.i_channels
=
330 __MIN( id
->p_encoder
->fmt_out
.audio
.i_channels
,
331 id
->p_decoder
->fmt_in
.audio
.i_channels
);
332 id
->p_encoder
->fmt_out
.audio
.i_original_channels
=
333 id
->p_decoder
->fmt_in
.audio
.i_physical_channels
;
334 id
->p_encoder
->fmt_out
.audio
.i_physical_channels
=
335 pi_channels_maps
[id
->p_encoder
->fmt_out
.audio
.i_channels
];
337 /* Build decoder -> filter -> encoder chain */
338 if( transcode_audio_new( p_stream
, id
) == VLC_EGENERIC
)
340 msg_Err( p_stream
, "cannot create audio chain" );
344 /* Open output stream */
345 id
->id
= sout_StreamIdAdd( p_stream
->p_next
, &id
->p_encoder
->fmt_out
);
346 id
->b_transcode
= true;
350 transcode_audio_close( id
);
354 /* Reinit encoder again later on, when all information from decoders
356 if( id
->p_encoder
->p_module
)
358 module_unneed( id
->p_encoder
, id
->p_encoder
->p_module
);
359 id
->p_encoder
->p_module
= NULL
;
360 if( id
->p_encoder
->fmt_out
.p_extra
)
362 free( id
->p_encoder
->fmt_out
.p_extra
);
363 id
->p_encoder
->fmt_out
.p_extra
= NULL
;
364 id
->p_encoder
->fmt_out
.i_extra
= 0;
366 if( id
->p_af_chain
!= NULL
)
367 aout_FiltersDelete( (vlc_object_t
*)NULL
, id
->p_af_chain
);
368 id
->p_af_chain
= NULL
;
371 date_Init( &id
->interpolated_pts
, p_fmt
->audio
.i_rate
, 1 );