transcode: fix encoder chroma initialization
[vlc.git] / modules / stream_out / transcode / audio.c
blob4829ea9c11055f19c2f0643617f9d65b70d13a24
1 /*****************************************************************************
2 * audio.c: transcoding stream output module (audio)
3 *****************************************************************************
4 * Copyright (C) 2003-2009 VLC authors and VideoLAN
5 * $Id$
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 /*****************************************************************************
28 * Preamble
29 *****************************************************************************/
31 #include "transcode.h"
33 #include <vlc_aout.h>
34 #include <vlc_input.h>
35 #include <vlc_meta.h>
36 #include <vlc_modules.h>
38 static const int pi_channels_maps[9] =
41 AOUT_CHAN_CENTER,
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
55 | AOUT_CHAN_LFE,
58 static int audio_update_format( decoder_t *p_dec )
60 aout_FormatPrepare( &p_dec->fmt_out.audio );
61 return ( p_dec->fmt_out.audio.i_bitspersample > 0 ) ? 0 : -1;
64 static int transcode_audio_initialize_filters( sout_stream_t *p_stream, sout_stream_id_sys_t *id,
65 sout_stream_sys_t *p_sys, audio_sample_format_t *fmt_last )
67 /* Load user specified audio filters */
68 /* XXX: These variable names come kinda out of nowhere... */
69 var_Create( p_stream, "audio-time-stretch", VLC_VAR_BOOL );
70 var_Create( p_stream, "audio-filter", VLC_VAR_STRING );
71 if( p_sys->psz_af )
72 var_SetString( p_stream, "audio-filter", p_sys->psz_af );
73 id->p_af_chain = aout_FiltersNew( p_stream, fmt_last,
74 &id->p_encoder->fmt_in.audio, NULL, NULL );
75 var_Destroy( p_stream, "audio-filter" );
76 var_Destroy( p_stream, "audio-time-stretch" );
77 if( id->p_af_chain == NULL )
79 msg_Err( p_stream, "Unable to initialize audio filters" );
80 module_unneed( id->p_encoder, id->p_encoder->p_module );
81 id->p_encoder->p_module = NULL;
82 module_unneed( id->p_decoder, id->p_decoder->p_module );
83 id->p_decoder->p_module = NULL;
84 return VLC_EGENERIC;
86 id->fmt_audio.i_rate = fmt_last->i_rate;
87 id->fmt_audio.i_physical_channels = fmt_last->i_physical_channels;
88 return VLC_SUCCESS;
91 static int transcode_audio_initialize_encoder( sout_stream_id_sys_t *id, sout_stream_t *p_stream )
93 sout_stream_sys_t *p_sys = p_stream->p_sys;
94 /* Initialization of encoder format structures */
95 es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
96 id->p_decoder->fmt_out.i_codec );
97 id->p_encoder->fmt_in.audio.i_format = id->p_decoder->fmt_out.i_codec;
98 id->p_encoder->fmt_in.audio.i_rate = id->p_encoder->fmt_out.audio.i_rate;
99 id->p_encoder->fmt_in.audio.i_physical_channels =
100 id->p_encoder->fmt_out.audio.i_physical_channels;
101 aout_FormatPrepare( &id->p_encoder->fmt_in.audio );
103 id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg;
104 id->p_encoder->p_module =
105 module_need( id->p_encoder, "encoder", p_sys->psz_aenc, true );
106 /* p_sys->i_acodec = 0 if there isn't acodec defined */
107 if( !id->p_encoder->p_module && p_sys->i_acodec )
109 msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s). "
110 "Take a look few lines earlier to see possible reason.",
111 p_sys->psz_aenc ? p_sys->psz_aenc : "any",
112 (char *)&p_sys->i_acodec );
113 module_unneed( id->p_decoder, id->p_decoder->p_module );
114 id->p_decoder->p_module = NULL;
115 return VLC_EGENERIC;
118 id->p_encoder->fmt_out.i_codec =
119 vlc_fourcc_GetCodec( AUDIO_ES, id->p_encoder->fmt_out.i_codec );
121 /* Fix input format */
122 id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
123 if( !id->p_encoder->fmt_in.audio.i_physical_channels )
125 if( id->p_encoder->fmt_in.audio.i_channels < (sizeof(pi_channels_maps) / sizeof(*pi_channels_maps)) )
126 id->p_encoder->fmt_in.audio.i_physical_channels =
127 pi_channels_maps[id->p_encoder->fmt_in.audio.i_channels];
129 aout_FormatPrepare( &id->p_encoder->fmt_in.audio );
131 return VLC_SUCCESS;
134 static int decoder_queue_audio( decoder_t *p_dec, block_t *p_audio )
136 sout_stream_id_sys_t *id = p_dec->p_queue_ctx;
138 vlc_mutex_lock(&id->fifo.lock);
139 *id->fifo.audio.last = p_audio;
140 id->fifo.audio.last = &p_audio->p_next;
141 vlc_mutex_unlock(&id->fifo.lock);
142 return 0;
145 static block_t *transcode_dequeue_all_audios( sout_stream_id_sys_t *id )
147 vlc_mutex_lock(&id->fifo.lock);
148 block_t *p_audio_bufs = id->fifo.audio.first;
149 id->fifo.audio.first = NULL;
150 id->fifo.audio.last = &id->fifo.audio.first;
151 vlc_mutex_unlock(&id->fifo.lock);
153 return p_audio_bufs;
156 static int transcode_audio_new( sout_stream_t *p_stream,
157 sout_stream_id_sys_t *id )
159 sout_stream_sys_t *p_sys = p_stream->p_sys;
160 audio_sample_format_t fmt_last;
163 * Open decoder
166 /* Initialization of decoder structures */
168 /* No need to clean the fmt_out, it was freshly initialized by
169 * es_format_Init in Add() */
170 es_format_Copy( &id->p_decoder->fmt_out, &id->p_decoder->fmt_in );
171 free( id->p_decoder->fmt_out.p_extra );
172 id->p_decoder->fmt_out.i_extra = 0;
173 id->p_decoder->fmt_out.p_extra = NULL;
174 id->p_decoder->pf_decode = NULL;
175 id->p_decoder->pf_queue_audio = decoder_queue_audio;
176 id->p_decoder->p_queue_ctx = id;
177 id->p_decoder->pf_aout_format_update = audio_update_format;
178 /* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */
179 id->p_decoder->p_module =
180 module_need( id->p_decoder, "audio decoder", "$codec", false );
181 if( !id->p_decoder->p_module )
183 msg_Err( p_stream, "cannot find audio decoder" );
184 return VLC_EGENERIC;
186 /* decoders don't set audio.i_format, but audio filters use it */
187 id->p_decoder->fmt_out.audio.i_format = id->p_decoder->fmt_out.i_codec;
188 aout_FormatPrepare( &id->p_decoder->fmt_out.audio );
189 fmt_last = id->p_decoder->fmt_out.audio;
190 /* Fix AAC SBR changing number of channels and sampling rate */
191 if( !(id->p_decoder->fmt_in.i_codec == VLC_CODEC_MP4A &&
192 fmt_last.i_rate != id->p_encoder->fmt_in.audio.i_rate &&
193 fmt_last.i_channels != id->p_encoder->fmt_in.audio.i_channels) )
194 fmt_last.i_rate = id->p_decoder->fmt_in.audio.i_rate;
197 * Open encoder
199 if( transcode_audio_initialize_encoder( id, p_stream ) == VLC_EGENERIC )
200 return VLC_EGENERIC;
202 if( unlikely( transcode_audio_initialize_filters( p_stream, id, p_sys,
203 &fmt_last ) != VLC_SUCCESS ) )
204 return VLC_EGENERIC;
206 return VLC_SUCCESS;
209 void transcode_audio_close( sout_stream_id_sys_t *id )
211 /* Close decoder */
212 if( id->p_decoder->p_module )
213 module_unneed( id->p_decoder, id->p_decoder->p_module );
214 id->p_decoder->p_module = NULL;
216 if( id->p_decoder->p_description )
217 vlc_meta_Delete( id->p_decoder->p_description );
218 id->p_decoder->p_description = NULL;
220 /* Close encoder */
221 if( id->p_encoder->p_module )
222 module_unneed( id->p_encoder, id->p_encoder->p_module );
223 id->p_encoder->p_module = NULL;
225 /* Close filters */
226 if( id->p_af_chain != NULL )
227 aout_FiltersDelete( (vlc_object_t *)NULL, id->p_af_chain );
230 int transcode_audio_process( sout_stream_t *p_stream,
231 sout_stream_id_sys_t *id,
232 block_t *in, block_t **out )
234 sout_stream_sys_t *p_sys = p_stream->p_sys;
235 *out = NULL;
236 bool b_error = false;
238 int ret = id->p_decoder->pf_decode( id->p_decoder, in );
239 if( ret != VLCDEC_SUCCESS )
240 return VLC_EGENERIC;
242 block_t *p_audio_bufs = transcode_dequeue_all_audios( id );
243 if( p_audio_bufs == NULL )
244 goto end;
248 block_t *p_audio_buf = p_audio_bufs;
249 p_audio_bufs = p_audio_bufs->p_next;
250 p_audio_buf->p_next = NULL;
252 if( b_error )
254 block_Release( p_audio_buf );
255 continue;
258 if( unlikely( !id->p_encoder->p_module ) )
260 /* Complete destination format */
261 id->p_encoder->fmt_out.i_codec = p_sys->i_acodec;
262 id->p_encoder->fmt_out.audio.i_rate = p_sys->i_sample_rate > 0 ?
263 p_sys->i_sample_rate : id->p_decoder->fmt_out.audio.i_rate;
264 id->p_encoder->fmt_out.i_bitrate = p_sys->i_abitrate;
265 id->p_encoder->fmt_out.audio.i_bitspersample =
266 id->p_decoder->fmt_out.audio.i_bitspersample;
267 id->p_encoder->fmt_out.audio.i_channels = p_sys->i_channels > 0 ?
268 p_sys->i_channels : id->p_decoder->fmt_out.audio.i_channels;
270 id->p_encoder->fmt_in.audio.i_physical_channels =
271 id->p_encoder->fmt_out.audio.i_physical_channels =
272 pi_channels_maps[id->p_encoder->fmt_out.audio.i_channels];
274 if( transcode_audio_initialize_encoder( id, p_stream ) )
276 msg_Err( p_stream, "cannot create audio chain" );
277 goto error;
279 if( unlikely( transcode_audio_initialize_filters( p_stream, id, p_sys,
280 &id->p_decoder->fmt_out.audio ) != VLC_SUCCESS ) )
281 goto error;
282 date_Init( &id->next_input_pts, id->p_decoder->fmt_out.audio.i_rate, 1 );
283 date_Set( &id->next_input_pts, p_audio_buf->i_pts );
286 /* Check if audio format has changed, and filters need reinit */
287 if( unlikely( ( id->p_decoder->fmt_out.audio.i_rate != id->fmt_audio.i_rate ) ||
288 ( id->p_decoder->fmt_out.audio.i_physical_channels != id->fmt_audio.i_physical_channels ) ) )
290 msg_Info( p_stream, "Audio changed, trying to reinitialize filters" );
291 if( id->p_af_chain != NULL )
292 aout_FiltersDelete( (vlc_object_t *)NULL, id->p_af_chain );
294 /* decoders don't set audio.i_format, but audio filters use it */
295 id->p_decoder->fmt_out.audio.i_format = id->p_decoder->fmt_out.i_codec;
296 aout_FormatPrepare( &id->p_decoder->fmt_out.audio );
298 if( transcode_audio_initialize_filters( p_stream, id, p_sys,
299 &id->p_decoder->fmt_out.audio ) != VLC_SUCCESS )
300 goto error;
302 /* Set next_input_pts to run with new samplerate */
303 date_Init( &id->next_input_pts, id->fmt_audio.i_rate, 1 );
304 date_Set( &id->next_input_pts, p_audio_buf->i_pts );
307 if( p_sys->b_master_sync )
309 mtime_t i_pts = date_Get( &id->next_input_pts );
310 mtime_t i_drift = 0;
312 if( likely( p_audio_buf->i_pts != VLC_TS_INVALID ) )
313 i_drift = p_audio_buf->i_pts - i_pts;
315 if ( unlikely(i_drift > MASTER_SYNC_MAX_DRIFT
316 || i_drift < -MASTER_SYNC_MAX_DRIFT) )
318 msg_Dbg( p_stream,
319 "audio drift is too high (%"PRId64"), resetting master sync",
320 i_drift );
321 date_Set( &id->next_input_pts, p_audio_buf->i_pts );
322 i_pts = date_Get( &id->next_input_pts );
323 if( likely(p_audio_buf->i_pts != VLC_TS_INVALID ) )
324 i_drift = p_audio_buf->i_pts - i_pts;
326 p_sys->i_master_drift = i_drift;
327 date_Increment( &id->next_input_pts, p_audio_buf->i_nb_samples );
330 p_audio_buf->i_dts = p_audio_buf->i_pts;
332 /* Run filter chain */
333 p_audio_buf = aout_FiltersPlay( id->p_af_chain, p_audio_buf,
334 INPUT_RATE_DEFAULT );
335 if( !p_audio_buf )
337 b_error = true;
338 continue;
341 p_audio_buf->i_dts = p_audio_buf->i_pts;
343 block_t *p_block = id->p_encoder->pf_encode_audio( id->p_encoder, p_audio_buf );
345 block_ChainAppend( out, p_block );
346 block_Release( p_audio_buf );
347 continue;
348 error:
349 block_Release( p_audio_buf );
350 b_error = true;
351 } while( p_audio_bufs );
353 end:
354 /* Drain encoder */
355 if( unlikely( !b_error && in == NULL ) )
357 block_t *p_block;
358 do {
359 p_block = id->p_encoder->pf_encode_audio(id->p_encoder, NULL );
360 block_ChainAppend( out, p_block );
361 } while( p_block );
364 return b_error ? VLC_EGENERIC : VLC_SUCCESS;
367 bool transcode_audio_add( sout_stream_t *p_stream, const es_format_t *p_fmt,
368 sout_stream_id_sys_t *id )
370 sout_stream_sys_t *p_sys = p_stream->p_sys;
372 msg_Dbg( p_stream,
373 "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
374 (char*)&p_fmt->i_codec, (char*)&p_sys->i_acodec );
376 id->fifo.audio.first = NULL;
377 id->fifo.audio.last = &id->fifo.audio.first;
379 /* Complete destination format */
380 id->p_encoder->fmt_out.i_codec = p_sys->i_acodec;
381 id->p_encoder->fmt_out.audio.i_rate = p_sys->i_sample_rate > 0 ?
382 p_sys->i_sample_rate : p_fmt->audio.i_rate;
383 id->p_encoder->fmt_out.i_bitrate = p_sys->i_abitrate;
384 id->p_encoder->fmt_out.audio.i_bitspersample =
385 p_fmt->audio.i_bitspersample;
386 id->p_encoder->fmt_out.audio.i_channels = p_sys->i_channels > 0 ?
387 p_sys->i_channels : p_fmt->audio.i_channels;
389 id->p_encoder->fmt_in.audio.i_physical_channels =
390 id->p_encoder->fmt_out.audio.i_physical_channels =
391 pi_channels_maps[id->p_encoder->fmt_out.audio.i_channels];
393 /* Build decoder -> filter -> encoder chain */
394 if( transcode_audio_new( p_stream, id ) == VLC_EGENERIC )
396 msg_Err( p_stream, "cannot create audio chain" );
397 return false;
400 /* Open output stream */
401 id->id = sout_StreamIdAdd( p_stream->p_next, &id->p_encoder->fmt_out );
402 id->b_transcode = true;
404 if( !id->id )
406 transcode_audio_close( id );
407 return false;
410 /* Reinit encoder again later on, when all information from decoders
411 * is available. */
412 if( id->p_encoder->p_module )
414 module_unneed( id->p_encoder, id->p_encoder->p_module );
415 id->p_encoder->p_module = NULL;
416 if( id->p_encoder->fmt_out.p_extra )
418 free( id->p_encoder->fmt_out.p_extra );
419 id->p_encoder->fmt_out.p_extra = NULL;
420 id->p_encoder->fmt_out.i_extra = 0;
422 if( id->p_af_chain != NULL )
423 aout_FiltersDelete( (vlc_object_t *)NULL, id->p_af_chain );
424 id->p_af_chain = NULL;
426 return true;