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