Index: libmpcodecs/ad_faad.c
===================================================================
--- libmpcodecs/ad_faad.c	(リビジョン 29813)
+++ libmpcodecs/ad_faad.c	(作業コピー)
@@ -296,6 +296,17 @@
       mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"FAAD: Successfully decoded frame (%ld Bytes)!\n",
       sh->samplesize*faac_finfo.samples);
 
+      if (sh->channels != faac_finfo.channels)
+      {
+          mp_msg(MSGT_DECAUDIO, MSGL_DBG2, "FAAD: changed the number of channels(to %d)\n", faac_finfo.channels);
+          sh->channels = faac_finfo.channels;
+      }
+      if (sh->samplerate != faac_finfo.samplerate)
+      {
+          mp_msg(MSGT_DECAUDIO, MSGL_DBG2, "FAAD: changed the sampling rate(to %lu)\n", faac_finfo.samplerate);
+          sh->samplerate = faac_finfo.samplerate;
+      }
+
       if (sh->channels >= 5)
         reorder_channel_copy_nch(faac_sample_buffer,
                                  AF_CHANNEL_LAYOUT_AAC_DEFAULT,
Index: libfaad2/decoder.c
===================================================================
--- libfaad2/decoder.c	(リビジョン 29813)
+++ libfaad2/decoder.c	(作業コピー)
@@ -252,7 +252,7 @@
         {
             int32_t x;
             hDecoder->latm_header_present = 1;
-            x = NeAACDecInit2(hDecoder, &l->ASC, (l->ASCbits+7)/8, samplerate, channels);
+            x = NeAACDecInit2(hDecoder, l->ASC, (l->ASCbits+7)/8, samplerate, channels);
             if(x!=0)
                 hDecoder->latm_header_present = 0;
             return x;
@@ -300,7 +300,6 @@
         }
         faad_endbits(&ld);
     }
-    hDecoder->channelConfiguration = *channels;
 
 #if (defined(PS_DEC) || defined(DRM_PS))
     /* check if we have a mono file */
@@ -311,6 +310,8 @@
     }
 #endif
 
+    hDecoder->channelConfiguration = *channels;
+
 #ifdef SBR_DEC
     /* implicit signalling */
     if (*samplerate <= 24000 && !(hDecoder->config.dontUpSampleImplicitSBR))
@@ -568,8 +569,14 @@
         chdir = hInfo->num_front_channels;
         if (chdir & 1)
         {
+#if (defined(PS_DEC) || defined(DRM_PS))
+            /* When PS is enabled output is always stereo */
+            hInfo->channel_position[chpos++] = FRONT_CHANNEL_LEFT;
+            hInfo->channel_position[chpos++] = FRONT_CHANNEL_RIGHT;
+#else
             hInfo->channel_position[chpos++] = FRONT_CHANNEL_CENTER;
             chdir--;
+#endif
         }
         for (i = 0; i < chdir; i += 2)
         {
@@ -608,8 +615,15 @@
         switch (hDecoder->channelConfiguration)
         {
         case 1:
+#if (defined(PS_DEC) || defined(DRM_PS))
+            hInfo->num_front_channels = 2;
+            /* When PS is enabled output is always stereo */
+            hInfo->channel_position[0] = FRONT_CHANNEL_LEFT;
+            hInfo->channel_position[1] = FRONT_CHANNEL_RIGHT;
+#else
             hInfo->num_front_channels = 1;
             hInfo->channel_position[0] = FRONT_CHANNEL_CENTER;
+#endif
             break;
         case 2:
             hInfo->num_front_channels = 2;
@@ -852,6 +866,16 @@
         if ((hInfo->error = adts_frame(&adts, &ld)) > 0)
             goto error;
 
+        if (adts.channel_configuration != hDecoder->fr_channels)
+        {
+            //hDecoder->postSeekResetFlag = 1;
+            //hDecoder->pce_set = 0;
+            //memset(hDecoder->element_id, 0, sizeof(hDecoder->element_id));
+            memset(hDecoder->element_output_channels, 0,
+                   sizeof(hDecoder->element_output_channels));
+            memset(hDecoder->element_alloced, 0,
+                   sizeof(hDecoder->element_alloced));
+        }
         /* MPEG2 does byte_alignment() here,
          * but ADTS header is always multiple of 8 bits in MPEG2
          * so not needed to actually do it.
@@ -938,6 +962,8 @@
         output_channels = 2;
     }
 #endif
+    if (hDecoder->adts_header_present || hDecoder->adif_header_present)
+        hDecoder->channelConfiguration = output_channels;
 
     /* Make a channel configuration based on either a PCE or a channelConfiguration */
     create_channel_config(hDecoder, hInfo);
@@ -963,6 +989,7 @@
 #if (defined(PS_DEC) || defined(DRM_PS))
     hInfo->ps = hDecoder->ps_used_global;
 #endif
+//{fprintf(stderr, "chconfig:%d fr-ch:%d hI-ch:%d elm_out[0]:%d alloced:%d up:%d ps:%d\n", hDecoder->channelConfiguration, hDecoder->fr_channels, hInfo->channels, hDecoder->element_output_channels[0], hDecoder->alloced_channels, hDecoder->upMatrix, hDecoder->ps_used[0]);}
 
     /* check if frame has channel elements */
     if (channels == 0)
--- libfaad2/output.c	(リビジョン 29813)
+++ libfaad2/output.c	(作業コピー)
@@ -104,6 +104,7 @@
         }
         break;
     case CONV(2,0):
+    case CONV(2,1):
         if (hDecoder->upMatrix)
         {
             ch  = hDecoder->internal_channel[0];
@@ -569,6 +570,19 @@
     if (format != FAAD_FMT_16BIT)
         return output_to_PCM_sux(hDecoder, input, sample_buffer, channels, frame_len, format);
 
+    if (hDecoder->upMatrix) {
+        for(i = 0; i < frame_len; i++)
+        {
+            int32_t tmp = input[hDecoder->internal_channel[0]][i];
+            tmp += (1 << (REAL_BITS-1));
+            tmp >>= REAL_BITS;
+	        if ((tmp+0x8000) & ~0xffff) tmp = ~(tmp>>31)-0x8000;
+            for (ch = 0; ch < channels; ch++)
+                *(short_sample_buffer++) = tmp;
+        }
+        return sample_buffer;
+    }
+
     if (hDecoder->downMatrix) {
         for(i = 0; i < frame_len; i++)
         {
Index: libfaad2/specrec.c
===================================================================
--- libfaad2/specrec.c	(リビジョン 29813)
+++ libfaad2/specrec.c	(作業コピー)
@@ -847,9 +847,31 @@
     output_channels = 1;
 #endif
 
+/*
     if (hDecoder->element_alloced[hDecoder->fr_ch_ele] == 0 ||
         hDecoder->element_output_channels[hDecoder->fr_ch_ele] < output_channels) {
         hDecoder->element_output_channels[hDecoder->fr_ch_ele] = output_channels;
+*/
+    if (hDecoder->element_alloced[hDecoder->fr_ch_ele] == 0)
+    {
+        hDecoder->element_output_channels[hDecoder->fr_ch_ele] = output_channels;
+    } else if (hDecoder->element_output_channels[hDecoder->fr_ch_ele] != output_channels) {
+        /* element inconsistency */
+
+        /* this only happens if PS is actually found but not in the first frame
+         * this means that there is only 1 bitstream element!
+         */
+
+        /* reset the allocation */
+        hDecoder->element_alloced[hDecoder->fr_ch_ele] = 0;
+
+        hDecoder->element_output_channels[hDecoder->fr_ch_ele] = output_channels;
+
+        //return 21;
+    }
+
+    if (hDecoder->element_alloced[hDecoder->fr_ch_ele] == 0)
+    {
         retval = allocate_single_channel(hDecoder, sce->channel, output_channels);
         if (retval > 0)
             return retval;
@@ -995,10 +1017,12 @@
     {
         return 23;
     }
+#endif
 
     /* copy L to R when no PS is used */
 #if (defined(PS_DEC) || defined(DRM_PS))
-    if ((hDecoder->ps_used[hDecoder->fr_ch_ele] == 0) && (output_channels == 2))
+    if ((hDecoder->ps_used[hDecoder->fr_ch_ele] == 0) &&
+        (hDecoder->element_output_channels[hDecoder->fr_ch_ele] == 2))
     {
         uint8_t ele = hDecoder->fr_ch_ele;
         uint8_t ch = sce->channel;
@@ -1008,7 +1032,6 @@
         memcpy(hDecoder->time_out[ch+1], hDecoder->time_out[ch], frame_size);
     }
 #endif
-#endif
 
     return 0;
 }
Index: libfaad2/syntax.c
===================================================================
--- libfaad2/syntax.c	(リビジョン 29813)
+++ libfaad2/syntax.c	(作業コピー)
@@ -1514,6 +1514,7 @@
         if ((result = rvlc_decode_scale_factors(ics, ld)) > 0)
             return result;
     }
+#endif
 
     if (hDecoder->object_type >= ER_OBJECT_START)
     {
@@ -1528,6 +1529,7 @@
             return result;
 #endif
 
+#ifdef ERROR_RESILIENCE
     if (hDecoder->aacSpectralDataResilienceFlag)
     {
         /* error resilient spectral data decoding */
@@ -2128,7 +2130,7 @@
         n++;
         drc->num_bands += band_incr;
 
-        for (i = 0; i < drc->num_bands; i++);
+        for (i = 0; i < drc->num_bands; i++)
         {
             drc->band_top[i] = (uint8_t)faad_getbits(ld, 8
                 DEBUGVAR(1,97,"dynamic_range_info(): band_top"));
