1 /*****************************************************************************
2 * audio.c: audio decoder using libavcodec library
3 *****************************************************************************
4 * Copyright (C) 1999-2003 VLC authors and VideoLAN
5 * $Id: eec255ae0bd4e6a1f424d5bedd6895882a1ff461 $
6 *
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8 * Gildas Bazin <gbazin@videolan.org>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
24
25 /*****************************************************************************
26 * Preamble
27 *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <assert.h>
33
34 #include <vlc_common.h>
35 #include <vlc_aout.h>
36 #include <vlc_codec.h>
37 #include <vlc_avcodec.h>
38
39 #include "avcodec.h"
40
41 #include <libavcodec/avcodec.h>
42 #include <libavutil/mem.h>
43
44 #include <libavutil/channel_layout.h>
45
46
47 /*****************************************************************************
48 * decoder_sys_t : decoder descriptor
49 *****************************************************************************/
50 struct decoder_sys_t
51 {
52 AVCodecContext *p_context;
53 const AVCodec *p_codec;
54
55 /*
56 * Output properties
57 */
58 audio_sample_format_t aout_format;
59 date_t end_date;
60
61 /* */
62 int i_reject_count;
63
64 /* */
65 bool b_extract;
66 int pi_extraction[AOUT_CHAN_MAX];
67 int i_previous_channels;
68 uint64_t i_previous_layout;
69 };
70
71 #define BLOCK_FLAG_PRIVATE_REALLOCATED (1 << BLOCK_FLAG_PRIVATE_SHIFT)
72
73 static void SetupOutputFormat( decoder_t *p_dec, bool b_trust );
74 static block_t * ConvertAVFrame( decoder_t *p_dec, AVFrame *frame );
75 static int DecodeAudio( decoder_t *, block_t * );
76 static void Flush( decoder_t * );
77
InitDecoderConfig(decoder_t * p_dec,AVCodecContext * p_context)78 static void InitDecoderConfig( decoder_t *p_dec, AVCodecContext *p_context )
79 {
80 if( p_dec->fmt_in.i_extra > 0 )
81 {
82 const uint8_t * const p_src = p_dec->fmt_in.p_extra;
83
84 int i_offset = 0;
85 int i_size = p_dec->fmt_in.i_extra;
86
87 if( p_dec->fmt_in.i_codec == VLC_CODEC_ALAC )
88 {
89 static const uint8_t p_pattern[] = { 0, 0, 0, 36, 'a', 'l', 'a', 'c' };
90 /* Find alac atom XXX it is a bit ugly */
91 for( i_offset = 0; i_offset < i_size - (int)sizeof(p_pattern); i_offset++ )
92 {
93 if( !memcmp( &p_src[i_offset], p_pattern, sizeof(p_pattern) ) )
94 break;
95 }
96 i_size = __MIN( p_dec->fmt_in.i_extra - i_offset, 36 );
97 if( i_size < 36 )
98 i_size = 0;
99 }
100
101 if( i_size > 0 )
102 {
103 p_context->extradata =
104 av_malloc( i_size + FF_INPUT_BUFFER_PADDING_SIZE );
105 if( p_context->extradata )
106 {
107 uint8_t *p_dst = p_context->extradata;
108
109 p_context->extradata_size = i_size;
110
111 memcpy( &p_dst[0], &p_src[i_offset], i_size );
112 memset( &p_dst[i_size], 0, FF_INPUT_BUFFER_PADDING_SIZE );
113 }
114 }
115 }
116 else
117 {
118 p_context->extradata_size = 0;
119 p_context->extradata = NULL;
120 }
121 }
122
OpenAudioCodec(decoder_t * p_dec)123 static int OpenAudioCodec( decoder_t *p_dec )
124 {
125 decoder_sys_t *p_sys = p_dec->p_sys;
126 AVCodecContext *ctx = p_sys->p_context;
127 const AVCodec *codec = p_sys->p_codec;
128
129 if( ctx->extradata_size <= 0 )
130 {
131 if( codec->id == AV_CODEC_ID_VORBIS ||
132 ( codec->id == AV_CODEC_ID_AAC &&
133 !p_dec->fmt_in.b_packetized ) )
134 {
135 msg_Warn( p_dec, "waiting for extra data for codec %s",
136 codec->name );
137 return 1;
138 }
139 }
140
141 ctx->sample_rate = p_dec->fmt_in.audio.i_rate;
142 ctx->channels = p_dec->fmt_in.audio.i_channels;
143 ctx->block_align = p_dec->fmt_in.audio.i_blockalign;
144 ctx->bit_rate = p_dec->fmt_in.i_bitrate;
145 ctx->bits_per_coded_sample = p_dec->fmt_in.audio.i_bitspersample;
146
147 if( codec->id == AV_CODEC_ID_ADPCM_G726 &&
148 ctx->bit_rate > 0 &&
149 ctx->sample_rate > 0)
150 ctx->bits_per_coded_sample = ctx->bit_rate / ctx->sample_rate;
151
152 return ffmpeg_OpenCodec( p_dec, ctx, codec );
153 }
154
155 /**
156 * Allocates decoded audio buffer for libavcodec to use.
157 */
158 typedef struct
159 {
160 block_t self;
161 AVFrame *frame;
162 } vlc_av_frame_t;
163
vlc_av_frame_Release(block_t * block)164 static void vlc_av_frame_Release(block_t *block)
165 {
166 vlc_av_frame_t *b = (void *)block;
167
168 av_frame_free(&b->frame);
169 free(b);
170 }
171
vlc_av_frame_Wrap(AVFrame * frame)172 static block_t *vlc_av_frame_Wrap(AVFrame *frame)
173 {
174 for (unsigned i = 1; i < AV_NUM_DATA_POINTERS; i++)
175 assert(frame->linesize[i] == 0); /* only packed frame supported */
176
177 if (av_frame_make_writable(frame)) /* TODO: read-only block_t */
178 return NULL;
179
180 vlc_av_frame_t *b = malloc(sizeof (*b));
181 if (unlikely(b == NULL))
182 return NULL;
183
184 block_t *block = &b->self;
185
186 block_Init(block, frame->extended_data[0], frame->linesize[0]);
187 block->i_nb_samples = frame->nb_samples;
188 block->pf_release = vlc_av_frame_Release;
189 b->frame = frame;
190 return block;
191 }
192
193 /*****************************************************************************
194 * EndAudio: decoder destruction
195 *****************************************************************************
196 * This function is called when the thread ends after a successful
197 * initialization.
198 *****************************************************************************/
EndAudioDec(vlc_object_t * obj)199 void EndAudioDec( vlc_object_t *obj )
200 {
201 decoder_t *p_dec = (decoder_t *)obj;
202 decoder_sys_t *sys = p_dec->p_sys;
203 AVCodecContext *ctx = sys->p_context;
204
205 avcodec_free_context( &ctx );
206 free( sys );
207 }
208
209 /*****************************************************************************
210 * InitAudioDec: initialize audio decoder
211 *****************************************************************************
212 * The avcodec codec will be opened, some memory allocated.
213 *****************************************************************************/
InitAudioDec(vlc_object_t * obj)214 int InitAudioDec( vlc_object_t *obj )
215 {
216 decoder_t *p_dec = (decoder_t *)obj;
217 const AVCodec *codec;
218 AVCodecContext *avctx = ffmpeg_AllocContext( p_dec, &codec );
219 if( avctx == NULL )
220 return VLC_EGENERIC;
221
222 /* Allocate the memory needed to store the decoder's structure */
223 decoder_sys_t *p_sys = malloc(sizeof(*p_sys));
224 if( unlikely(p_sys == NULL) )
225 {
226 avcodec_free_context( &avctx );
227 return VLC_ENOMEM;
228 }
229
230 p_dec->p_sys = p_sys;
231 p_sys->p_context = avctx;
232 p_sys->p_codec = codec;
233
234 // Initialize decoder extradata
235 InitDecoderConfig( p_dec, avctx );
236
237 /* ***** Open the codec ***** */
238 if( OpenAudioCodec( p_dec ) < 0 )
239 {
240 free( p_sys );
241 avcodec_free_context( &avctx );
242 return VLC_EGENERIC;
243 }
244
245 p_sys->i_reject_count = 0;
246 p_sys->b_extract = false;
247 p_sys->i_previous_channels = 0;
248 p_sys->i_previous_layout = 0;
249
250 /* */
251 /* Try to set as much information as possible but do not trust it */
252 SetupOutputFormat( p_dec, false );
253
254 date_Set( &p_sys->end_date, VLC_TS_INVALID );
255 if( !p_dec->fmt_out.audio.i_rate )
256 p_dec->fmt_out.audio.i_rate = p_dec->fmt_in.audio.i_rate;
257 if( p_dec->fmt_out.audio.i_rate )
258 date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 );
259 p_dec->fmt_out.audio.i_chan_mode = p_dec->fmt_in.audio.i_chan_mode;
260
261 p_dec->pf_decode = DecodeAudio;
262 p_dec->pf_flush = Flush;
263
264 /* XXX: Writing input format makes little sense. */
265 if( avctx->profile != FF_PROFILE_UNKNOWN )
266 p_dec->fmt_in.i_profile = avctx->profile;
267 if( avctx->level != FF_LEVEL_UNKNOWN )
268 p_dec->fmt_in.i_level = avctx->level;
269
270 return VLC_SUCCESS;
271 }
272
273 /*****************************************************************************
274 * Flush:
275 *****************************************************************************/
Flush(decoder_t * p_dec)276 static void Flush( decoder_t *p_dec )
277 {
278 decoder_sys_t *p_sys = p_dec->p_sys;
279 AVCodecContext *ctx = p_sys->p_context;
280
281 if( avcodec_is_open( ctx ) )
282 avcodec_flush_buffers( ctx );
283 date_Set( &p_sys->end_date, VLC_TS_INVALID );
284
285 if( ctx->codec_id == AV_CODEC_ID_MP2 ||
286 ctx->codec_id == AV_CODEC_ID_MP3 )
287 p_sys->i_reject_count = 3;
288 }
289
290 /*****************************************************************************
291 * DecodeBlock: Called to decode one frame
292 *****************************************************************************/
DecodeBlock(decoder_t * p_dec,block_t ** pp_block)293 static int DecodeBlock( decoder_t *p_dec, block_t **pp_block )
294 {
295 decoder_sys_t *p_sys = p_dec->p_sys;
296 AVCodecContext *ctx = p_sys->p_context;
297 AVFrame *frame = NULL;
298 block_t *p_block = NULL;
299 bool b_error = false;
300
301 if( !ctx->extradata_size && p_dec->fmt_in.i_extra
302 && !avcodec_is_open( ctx ) )
303 {
304 InitDecoderConfig( p_dec, ctx );
305 OpenAudioCodec( p_dec );
306 }
307
308 if( !avcodec_is_open( ctx ) )
309 {
310 if( pp_block )
311 p_block = *pp_block;
312 goto drop;
313 }
314
315 if( pp_block == NULL ) /* Drain request */
316 {
317 /* we don't need to care about return val */
318 (void) avcodec_send_packet( ctx, NULL );
319 }
320 else
321 {
322 p_block = *pp_block;
323 }
324
325 if( p_block )
326 {
327 if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
328 {
329 Flush( p_dec );
330 goto drop;
331 }
332
333 if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
334 {
335 date_Set( &p_sys->end_date, VLC_TS_INVALID );
336 }
337
338 /* We've just started the stream, wait for the first PTS. */
339 if( !date_Get( &p_sys->end_date ) && p_block->i_pts <= VLC_TS_INVALID )
340 goto drop;
341
342 if( p_block->i_buffer <= 0 )
343 goto drop;
344
345 if( (p_block->i_flags & BLOCK_FLAG_PRIVATE_REALLOCATED) == 0 )
346 {
347 *pp_block = p_block = block_Realloc( p_block, 0, p_block->i_buffer + FF_INPUT_BUFFER_PADDING_SIZE );
348 if( !p_block )
349 goto end;
350 p_block->i_buffer -= FF_INPUT_BUFFER_PADDING_SIZE;
351 memset( &p_block->p_buffer[p_block->i_buffer], 0, FF_INPUT_BUFFER_PADDING_SIZE );
352
353 p_block->i_flags |= BLOCK_FLAG_PRIVATE_REALLOCATED;
354 }
355 }
356
357 frame = av_frame_alloc();
358 if (unlikely(frame == NULL))
359 goto end;
360
361 for( int ret = 0; ret == 0; )
362 {
363 /* Feed in the loop as buffer could have been full on first iterations */
364 if( p_block )
365 {
366 AVPacket pkt;
367 av_init_packet( &pkt );
368 pkt.data = p_block->p_buffer;
369 pkt.size = p_block->i_buffer;
370 ret = avcodec_send_packet( ctx, &pkt );
371 if( ret == 0 ) /* Block has been consumed */
372 {
373 /* Only set new pts from input block if it has been used,
374 * otherwise let it be through interpolation */
375 if( p_block->i_pts > date_Get( &p_sys->end_date ) )
376 {
377 date_Set( &p_sys->end_date, p_block->i_pts );
378 }
379
380 block_Release( p_block );
381 *pp_block = p_block = NULL;
382 }
383 else if ( ret != AVERROR(EAGAIN) ) /* Errors other than buffer full */
384 {
385 if( ret == AVERROR(ENOMEM) || ret == AVERROR(EINVAL) )
386 goto end;
387 else
388 goto drop;
389 }
390 }
391
392 /* Try to read one or multiple frames */
393 ret = avcodec_receive_frame( ctx, frame );
394 if( ret == 0 )
395 {
396 /* checks and init from first decoded frame */
397 if( ctx->channels <= 0 || ctx->channels > INPUT_CHAN_MAX
398 || ctx->sample_rate <= 0 )
399 {
400 msg_Warn( p_dec, "invalid audio properties channels count %d, sample rate %d",
401 ctx->channels, ctx->sample_rate );
402 goto drop;
403 }
404 else if( p_dec->fmt_out.audio.i_rate != (unsigned int)ctx->sample_rate )
405 {
406 date_Init( &p_sys->end_date, ctx->sample_rate, 1 );
407 }
408
409 SetupOutputFormat( p_dec, true );
410 if( decoder_UpdateAudioFormat( p_dec ) )
411 goto drop;
412
413 block_t *p_converted = ConvertAVFrame( p_dec, frame ); /* Consumes frame */
414 if( p_converted )
415 {
416 /* Silent unwanted samples */
417 if( p_sys->i_reject_count > 0 )
418 {
419 memset( p_converted->p_buffer, 0, p_converted->i_buffer );
420 p_sys->i_reject_count--;
421 }
422 p_converted->i_buffer = p_converted->i_nb_samples
423 * p_dec->fmt_out.audio.i_bytes_per_frame;
424 p_converted->i_pts = date_Get( &p_sys->end_date );
425 p_converted->i_length = date_Increment( &p_sys->end_date,
426 p_converted->i_nb_samples ) - p_converted->i_pts;
427
428 decoder_QueueAudio( p_dec, p_converted );
429 }
430
431 /* Prepare new frame */
432 frame = av_frame_alloc();
433 if (unlikely(frame == NULL))
434 break;
435 }
436 else
437 {
438 /* After draining, we need to reset decoder with a flush */
439 if( ret == AVERROR_EOF )
440 avcodec_flush_buffers( p_sys->p_context );
441 av_frame_free( &frame );
442 }
443 };
444
445 return VLCDEC_SUCCESS;
446
447 end:
448 b_error = true;
449 drop:
450 if( pp_block )
451 {
452 assert( *pp_block == p_block );
453 *pp_block = NULL;
454 }
455 if( p_block != NULL )
456 block_Release(p_block);
457 if( frame != NULL )
458 av_frame_free( &frame );
459
460 return (b_error) ? VLCDEC_ECRITICAL : VLCDEC_SUCCESS;
461 }
462
DecodeAudio(decoder_t * p_dec,block_t * p_block)463 static int DecodeAudio( decoder_t *p_dec, block_t *p_block )
464 {
465 block_t **pp_block = p_block ? &p_block : NULL;
466 int i_ret;
467 do
468 {
469 i_ret = DecodeBlock( p_dec, pp_block );
470 }
471 while( i_ret == VLCDEC_SUCCESS && pp_block && *pp_block );
472
473 return i_ret;
474 }
475
ConvertAVFrame(decoder_t * p_dec,AVFrame * frame)476 static block_t * ConvertAVFrame( decoder_t *p_dec, AVFrame *frame )
477 {
478 decoder_sys_t *p_sys = p_dec->p_sys;
479 AVCodecContext *ctx = p_sys->p_context;
480 block_t *p_block;
481
482 /* Interleave audio if required */
483 if( av_sample_fmt_is_planar( ctx->sample_fmt ) )
484 {
485 p_block = block_Alloc(frame->linesize[0] * ctx->channels);
486 if ( likely(p_block) )
487 {
488 const void *planes[ctx->channels];
489 for (int i = 0; i < ctx->channels; i++)
490 planes[i] = frame->extended_data[i];
491
492 aout_Interleave(p_block->p_buffer, planes, frame->nb_samples,
493 ctx->channels, p_dec->fmt_out.audio.i_format);
494 p_block->i_nb_samples = frame->nb_samples;
495 }
496 av_frame_free(&frame);
497 }
498 else
499 {
500 p_block = vlc_av_frame_Wrap(frame);
501 frame = NULL;
502 }
503
504 if (p_sys->b_extract && p_block)
505 { /* TODO: do not drop channels... at least not here */
506 block_t *p_buffer = block_Alloc( p_dec->fmt_out.audio.i_bytes_per_frame
507 * p_block->i_nb_samples );
508 if( likely(p_buffer) )
509 {
510 aout_ChannelExtract( p_buffer->p_buffer,
511 p_dec->fmt_out.audio.i_channels,
512 p_block->p_buffer, ctx->channels,
513 p_block->i_nb_samples, p_sys->pi_extraction,
514 p_dec->fmt_out.audio.i_bitspersample );
515 p_buffer->i_nb_samples = p_block->i_nb_samples;
516 }
517 block_Release( p_block );
518 p_block = p_buffer;
519 }
520
521 return p_block;
522 }
523
524 /*****************************************************************************
525 *
526 *****************************************************************************/
527
GetVlcAudioFormat(int fmt)528 vlc_fourcc_t GetVlcAudioFormat( int fmt )
529 {
530 static const vlc_fourcc_t fcc[] = {
531 [AV_SAMPLE_FMT_U8] = VLC_CODEC_U8,
532 [AV_SAMPLE_FMT_S16] = VLC_CODEC_S16N,
533 [AV_SAMPLE_FMT_S32] = VLC_CODEC_S32N,
534 [AV_SAMPLE_FMT_FLT] = VLC_CODEC_FL32,
535 [AV_SAMPLE_FMT_DBL] = VLC_CODEC_FL64,
536 [AV_SAMPLE_FMT_U8P] = VLC_CODEC_U8,
537 [AV_SAMPLE_FMT_S16P] = VLC_CODEC_S16N,
538 [AV_SAMPLE_FMT_S32P] = VLC_CODEC_S32N,
539 [AV_SAMPLE_FMT_FLTP] = VLC_CODEC_FL32,
540 [AV_SAMPLE_FMT_DBLP] = VLC_CODEC_FL64,
541 };
542 if( (sizeof(fcc) / sizeof(fcc[0])) > (unsigned)fmt )
543 return fcc[fmt];
544 return VLC_CODEC_S16N;
545 }
546
547 static const uint64_t pi_channels_map[][2] =
548 {
549 { AV_CH_FRONT_LEFT, AOUT_CHAN_LEFT },
550 { AV_CH_FRONT_RIGHT, AOUT_CHAN_RIGHT },
551 { AV_CH_FRONT_CENTER, AOUT_CHAN_CENTER },
552 { AV_CH_LOW_FREQUENCY, AOUT_CHAN_LFE },
553 { AV_CH_BACK_LEFT, AOUT_CHAN_REARLEFT },
554 { AV_CH_BACK_RIGHT, AOUT_CHAN_REARRIGHT },
555 { AV_CH_FRONT_LEFT_OF_CENTER, 0 },
556 { AV_CH_FRONT_RIGHT_OF_CENTER, 0 },
557 { AV_CH_BACK_CENTER, AOUT_CHAN_REARCENTER },
558 { AV_CH_SIDE_LEFT, AOUT_CHAN_MIDDLELEFT },
559 { AV_CH_SIDE_RIGHT, AOUT_CHAN_MIDDLERIGHT },
560 { AV_CH_TOP_CENTER, 0 },
561 { AV_CH_TOP_FRONT_LEFT, 0 },
562 { AV_CH_TOP_FRONT_CENTER, 0 },
563 { AV_CH_TOP_FRONT_RIGHT, 0 },
564 { AV_CH_TOP_BACK_LEFT, 0 },
565 { AV_CH_TOP_BACK_CENTER, 0 },
566 { AV_CH_TOP_BACK_RIGHT, 0 },
567 { AV_CH_STEREO_LEFT, 0 },
568 { AV_CH_STEREO_RIGHT, 0 },
569 };
570
SetupOutputFormat(decoder_t * p_dec,bool b_trust)571 static void SetupOutputFormat( decoder_t *p_dec, bool b_trust )
572 {
573 decoder_sys_t *p_sys = p_dec->p_sys;
574
575 p_dec->fmt_out.i_codec = GetVlcAudioFormat( p_sys->p_context->sample_fmt );
576 p_dec->fmt_out.audio.channel_type = p_dec->fmt_in.audio.channel_type;
577 p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec;
578 p_dec->fmt_out.audio.i_rate = p_sys->p_context->sample_rate;
579
580 /* */
581 if( p_sys->i_previous_channels == p_sys->p_context->channels &&
582 p_sys->i_previous_layout == p_sys->p_context->channel_layout )
583 return;
584 if( b_trust )
585 {
586 p_sys->i_previous_channels = p_sys->p_context->channels;
587 p_sys->i_previous_layout = p_sys->p_context->channel_layout;
588 }
589
590 const unsigned i_order_max = sizeof(pi_channels_map)/sizeof(*pi_channels_map);
591 uint32_t pi_order_src[i_order_max];
592
593 int i_channels_src = 0;
594 int64_t channel_layout =
595 p_sys->p_context->channel_layout ? p_sys->p_context->channel_layout :
596 av_get_default_channel_layout( p_sys->p_context->channels );
597
598 if( channel_layout )
599 {
600 for( unsigned i = 0; i < i_order_max
601 && i_channels_src < p_sys->p_context->channels; i++ )
602 {
603 if( channel_layout & pi_channels_map[i][0] )
604 pi_order_src[i_channels_src++] = pi_channels_map[i][1];
605 }
606
607 if( i_channels_src != p_sys->p_context->channels && b_trust )
608 msg_Err( p_dec, "Channel layout not understood" );
609
610 /* Detect special dual mono case */
611 if( i_channels_src == 2 && pi_order_src[0] == AOUT_CHAN_CENTER
612 && pi_order_src[1] == AOUT_CHAN_CENTER )
613 {
614 p_dec->fmt_out.audio.i_chan_mode |= AOUT_CHANMODE_DUALMONO;
615 pi_order_src[0] = AOUT_CHAN_LEFT;
616 pi_order_src[1] = AOUT_CHAN_RIGHT;
617 }
618
619 uint32_t i_layout_dst;
620 int i_channels_dst;
621 p_sys->b_extract = aout_CheckChannelExtraction( p_sys->pi_extraction,
622 &i_layout_dst, &i_channels_dst,
623 NULL, pi_order_src, i_channels_src );
624 if( i_channels_dst != i_channels_src && b_trust )
625 msg_Warn( p_dec, "%d channels are dropped", i_channels_src - i_channels_dst );
626
627 /* No reordering for Ambisonic order 1 channels encoded in AAC... */
628 if (p_dec->fmt_out.audio.channel_type == AUDIO_CHANNEL_TYPE_AMBISONICS
629 && p_dec->fmt_in.i_codec == VLC_CODEC_MP4A
630 && i_channels_src == 4)
631 p_sys->b_extract = false;
632
633 p_dec->fmt_out.audio.i_physical_channels = i_layout_dst;
634 }
635 else
636 {
637 msg_Warn( p_dec, "no channel layout found");
638 p_dec->fmt_out.audio.i_physical_channels = 0;
639 p_dec->fmt_out.audio.i_channels = p_sys->p_context->channels;
640 }
641
642 aout_FormatPrepare( &p_dec->fmt_out.audio );
643 }
644
645