diff -Nru vlc-1.1.8.orig//modules/codec/faad.c vlc-1.1.8/modules/codec/faad.c
--- vlc-1.1.8.orig//modules/codec/faad.c	2010-07-27 04:49:07.000000000 +0900
+++ vlc-1.1.8/modules/codec/faad.c	2011-04-02 20:05:40.261287002 +0900
@@ -74,6 +74,12 @@
     uint32_t pi_channel_positions[MAX_CHANNEL_POSITIONS];
 
     bool b_sbr, b_ps;
+
+    /* store parameters from input chain */
+    int  input_channels;
+    void*  p_extra_store;
+    void*  p_extra_work;
+    int  i_extra_store;
 };
 
 static const uint32_t pi_channels_in[MAX_CHANNEL_POSITIONS] =
@@ -148,14 +154,34 @@
     p_dec->fmt_out.audio.i_physical_channels =
         p_dec->fmt_out.audio.i_original_channels = 0;
 
+    p_sys->input_channels = -1;
+    p_sys->p_extra_store = NULL;
+    p_sys->p_extra_work = NULL;
+    p_sys->i_extra_store = 0;
+
     if( p_dec->fmt_in.i_extra > 0 )
     {
         /* We have a decoder config so init the handle */
         unsigned long i_rate;
         unsigned char i_channels;
 
-        if( faacDecInit2( p_sys->hfaad, p_dec->fmt_in.p_extra,
-                          p_dec->fmt_in.i_extra,
+        p_sys->p_extra_store = malloc( p_dec->fmt_in.i_extra );
+        p_sys->p_extra_work = malloc( p_dec->fmt_in.i_extra );
+        if( !p_sys->p_extra_store || !p_sys->p_extra_work ){
+            return VLC_ENOMEM;
+        }
+        memcpy( p_sys->p_extra_store, p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra );
+        memcpy( p_sys->p_extra_work, p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra );
+        p_sys->i_extra_store = p_dec->fmt_in.i_extra;
+
+        /* fix-up channel_configuration for ARIB dual-monoral */
+        if( (((uint8_t *)p_sys->p_extra_work)[1] & 0x78) == 0 ){
+            ((uint8_t *)p_sys->p_extra_work)[1] &= 0x87;
+            ((uint8_t *)p_sys->p_extra_work)[1] |= (p_dec->fmt_in.audio.i_channels << 3);
+            msg_Dbg( p_dec, "Open: channel_configuration dirty fix for ARIB." );
+        }
+
+        if( faacDecInit2( p_sys->hfaad, p_sys->p_extra_work, p_sys->i_extra_store,
                           &i_rate, &i_channels ) < 0 )
         {
             msg_Err( p_dec, "Failed to initialize faad using extra data" );
@@ -204,6 +230,7 @@
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
     block_t *p_block;
+    bool  b_extra_changed = false;
 
     if( !pp_block || !*pp_block ) return NULL;
 
@@ -256,14 +283,61 @@
         p_block->i_buffer = 0;
     }
 
-    if( p_dec->fmt_out.audio.i_rate == 0 && p_dec->fmt_in.i_extra > 0 )
+    /* check whether the contents of extra buffer is same */
+    if( p_dec->fmt_in.i_extra == p_sys->i_extra_store ){
+        if( p_dec->fmt_in.i_extra > 0 ){
+            b_extra_changed =
+                (memcmp( p_dec->fmt_in.p_extra, p_sys->p_extra_store, p_dec->fmt_in.i_extra ) != 0);
+            if( b_extra_changed ){
+                memcpy( p_sys->p_extra_store, p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra );
+                memcpy( p_sys->p_extra_work, p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra );
+            }
+        }
+    } else{
+        b_extra_changed = true;
+        if( p_dec->fmt_in.i_extra > 0 ){
+            p_sys->p_extra_store = realloc( p_sys->p_extra_store, p_dec->fmt_in.i_extra );
+            p_sys->p_extra_work = realloc( p_sys->p_extra_work, p_dec->fmt_in.i_extra );
+            memcpy( p_sys->p_extra_store, p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra );
+            memcpy( p_sys->p_extra_work, p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra );
+        } else{
+            if( p_sys->p_extra_store != NULL ){
+                free( p_sys->p_extra_store );
+                p_sys->p_extra_store = NULL;
+            }
+            if( p_sys->p_extra_work != NULL ){
+                free( p_sys->p_extra_work );
+                p_sys->p_extra_work = NULL;
+            }
+        }
+        p_sys->i_extra_store = p_dec->fmt_in.i_extra;
+    }
+
+    if( ((p_dec->fmt_out.audio.i_rate == 0) ||
+                (p_dec->fmt_in.audio.i_rate != p_dec->fmt_out.audio.i_rate) ||
+                (p_dec->fmt_in.audio.i_channels != p_sys->input_channels) || b_extra_changed) &&
+            p_dec->fmt_in.i_extra > 0 )
     {
         /* We have a decoder config so init the handle */
         unsigned long i_rate;
         unsigned char i_channels;
+        faacDecConfiguration *cfg;
+
+        /* fix-up channel_configuration for ARIB dual-monoral */
+        if( (((uint8_t *)p_sys->p_extra_work)[1] & 0x78) == 0 ){
+            ((uint8_t *)p_sys->p_extra_work)[1] &= 0x87;
+            ((uint8_t *)p_sys->p_extra_work)[1] |= (p_dec->fmt_in.audio.i_channels << 3);
+            msg_Dbg( p_dec, "Decode: channel_configuration dirty fix for ARIB." );
+        }
 
-        if( faacDecInit2( p_sys->hfaad, p_dec->fmt_in.p_extra,
-                          p_dec->fmt_in.i_extra,
+        faacDecClose( p_sys->hfaad );
+        if( (p_sys->hfaad = faacDecOpen()) == NULL ){
+            msg_Err( p_dec, "decoder re-openning failed (cannot obtain handle)." );
+            block_Release( p_block );
+            return NULL;
+        }
+
+        if( faacDecInit2( p_sys->hfaad, p_sys->p_extra_work, p_sys->i_extra_store,
                           &i_rate, &i_channels ) >= 0 )
         {
             p_dec->fmt_out.audio.i_rate = i_rate;
@@ -273,22 +347,54 @@
                 = pi_channels_guessed[i_channels];
 
             date_Init( &p_sys->date, i_rate, 1 );
+            p_sys->input_channels = p_dec->fmt_in.audio.i_channels;
+            msg_Dbg( p_dec, "init2-2: %d, %d", i_channels, i_rate );
+        } else{
+            msg_Dbg( p_dec, "init2-2: failed." );
+            block_Release( p_block );
+            return NULL;
         }
+        /* Set the faad config */
+        cfg = faacDecGetCurrentConfiguration( p_sys->hfaad );
+        if (HAVE_FPU)
+            cfg->outputFormat = FAAD_FMT_FLOAT;
+        else
+            cfg->outputFormat = FAAD_FMT_16BIT;
+        faacDecSetConfiguration( p_sys->hfaad, cfg );
     }
 
-    if( p_dec->fmt_out.audio.i_rate == 0 && p_sys->i_buffer )
+    if( ((p_dec->fmt_out.audio.i_rate == 0) ||
+                (p_dec->fmt_in.audio.i_rate != p_dec->fmt_out.audio.i_rate) ||
+                (p_dec->fmt_in.audio.i_channels != p_sys->input_channels)) &&
+            p_sys->i_buffer )
     {
         unsigned long i_rate;
         unsigned char i_channels;
+        faacDecConfiguration *cfg;
 
         /* Init faad with the first frame */
+	faacDecClose( p_sys->hfaad );
+        if( (p_sys->hfaad = faacDecOpen()) == NULL ){
+            msg_Err( p_dec, "decoder re-openning failed (cannot obtain handle)." );
+            exit( 1 );
+        }
         if( faacDecInit( p_sys->hfaad,
                          p_sys->p_buffer, p_sys->i_buffer,
                          &i_rate, &i_channels ) < 0 )
         {
+            msg_Dbg( p_dec, "init1-2: failed." );
             block_Release( p_block );
             return NULL;
         }
+        msg_Dbg( p_dec, "init1-2: %d, %d", i_channels, i_rate );
+
+        /* Set the faad config */
+        cfg = faacDecGetCurrentConfiguration( p_sys->hfaad );
+        if (HAVE_FPU)
+            cfg->outputFormat = FAAD_FMT_FLOAT;
+        else
+            cfg->outputFormat = FAAD_FMT_16BIT;
+        faacDecSetConfiguration( p_sys->hfaad, cfg );
 
         p_dec->fmt_out.audio.i_rate = i_rate;
         p_dec->fmt_out.audio.i_channels = i_channels;
@@ -296,6 +402,7 @@
             = p_dec->fmt_out.audio.i_original_channels
             = pi_channels_guessed[i_channels];
         date_Init( &p_sys->date, i_rate, 1 );
+        p_sys->input_channels = p_dec->fmt_in.audio.i_channels;
     }
 
     if( p_block->i_pts > VLC_TS_INVALID && p_block->i_pts != date_Get( &p_sys->date ) )
@@ -324,6 +431,25 @@
         if( frame.error > 0 )
         {
             msg_Warn( p_dec, "%s", faacDecGetErrorMessage( frame.error ) );
+if (frame.error == 21)  {
+    /* Re Init Decoder */
+    faacDecHandle *hfaad;
+    faacDecConfiguration *cfg,*oldcfg;
+    unsigned long i_rate;
+    unsigned char i_channels;
+    oldcfg = faacDecGetCurrentConfiguration( p_sys->hfaad );
+    hfaad = faacDecOpen();
+    cfg = faacDecGetCurrentConfiguration( hfaad );
+    if (oldcfg->defSampleRate)
+      cfg->defSampleRate = oldcfg->defSampleRate;
+    cfg->defObjectType = oldcfg->defObjectType;
+    cfg->outputFormat = oldcfg->outputFormat;
+    faacDecSetConfiguration( hfaad, cfg );
+    faacDecInit( hfaad, p_sys->p_buffer, p_sys->i_buffer,&i_rate,&i_channels );
+    faacDecClose( p_sys->hfaad );
+    p_sys->hfaad = hfaad;
+}
+
 
             /* Flush the buffer */
             p_sys->i_buffer = 0;
diff -Nru vlc-1.1.8.orig//modules/packetizer/mpeg4audio.c vlc-1.1.8/modules/packetizer/mpeg4audio.c
--- vlc-1.1.8.orig//modules/packetizer/mpeg4audio.c	2010-04-13 09:22:27.000000000 +0900
+++ vlc-1.1.8/modules/packetizer/mpeg4audio.c	2011-04-02 20:04:50.301287002 +0900
@@ -138,6 +138,11 @@
     /* LOAS */
     bool b_latm_cfg;
     latm_mux_t latm;
+
+    /* ADTS */
+    /* store channels and sample-rate of last frame */
+    int  adts_channels;
+    int  adts_rate;
 };
 
 enum {
@@ -208,6 +213,7 @@
     date_Set( &p_sys->end_date, 0 );
     p_sys->bytestream = block_BytestreamInit();
     p_sys->b_latm_cfg = false;
+    p_sys->adts_channels = p_sys->adts_rate = -1;
 
     /* Set output properties */
     p_dec->fmt_out.i_cat = AUDIO_ES;
@@ -330,6 +336,12 @@
 {
     int i_profile, i_sample_rate_idx, i_frame_size;
     bool b_crc;
+    int  old_chans;
+    int  old_rate;
+    int  actual_channels;
+
+    old_chans = *pi_channels;
+    old_rate = *pi_sample_rate;
 
     /* Fixed header between frames */
     //int i_id = ( (p_buf[1] >> 3) & 0x01) ? 2 : 4; /* MPEG-2 or 4 */
@@ -350,11 +362,16 @@
     //uint16_t buffer_fullness = ((p_buf[5] & 0x1f) << 6) | (p_buf[6] >> 2);
     unsigned short i_raw_blocks_in_frame = p_buf[6] & 0x03;
 
-    if( !*pi_sample_rate || !*pi_channels || !i_frame_size )
+    /* dirty-hack for ARIB dual-monoral */
+    actual_channels = *pi_channels;
+    if( !*pi_sample_rate || !i_frame_size )
     {
         msg_Warn( p_dec, "Invalid ADTS header" );
         return 0;
     }
+    if( *pi_channels == 0 ){
+        *pi_channels = 2;
+    }
 
     *pi_frame_length = 1024;
 
@@ -398,11 +415,12 @@
 #endif
     }
 
-
     /* Build the decoder specific info header */
-    if( !p_dec->fmt_out.i_extra )
+    if( !p_dec->fmt_out.i_extra || (*pi_sample_rate != old_rate) || (actual_channels != old_chans) )
     {
-        p_dec->fmt_out.p_extra = malloc( 2 );
+        if( !p_dec->fmt_out.p_extra ){
+            p_dec->fmt_out.p_extra = malloc( 2 );
+        }
         if( !p_dec->fmt_out.p_extra )
         {
             p_dec->fmt_out.i_extra = 0;
@@ -412,7 +430,7 @@
         ((uint8_t *)p_dec->fmt_out.p_extra)[0] =
             (i_profile + 1) << 3 | (i_sample_rate_idx >> 1);
         ((uint8_t *)p_dec->fmt_out.p_extra)[1] =
-            ((i_sample_rate_idx & 0x01) << 7) | (*pi_channels <<3);
+            ((i_sample_rate_idx & 0x01) << 7) | (actual_channels << 3);
     }
 
     /* ADTS header length */
@@ -985,6 +1003,7 @@
         if( (*pp_block)->i_flags&BLOCK_FLAG_CORRUPTED )
         {
             p_sys->i_state = STATE_NOSYNC;
+            p_sys->adts_channels = p_sys->adts_rate = -1;
             block_BytestreamEmpty( &p_sys->bytestream );
         }
         date_Set( &p_sys->end_date, 0 );
@@ -1062,11 +1081,39 @@
                 }
 
                 /* Check if frame is valid and get frame info */
+                p_sys->i_channels = p_sys->adts_channels;
+                p_sys->i_rate = p_sys->adts_rate;
                 p_sys->i_frame_size = ADTSSyncInfo( p_dec, p_header,
                                                     &p_sys->i_channels,
                                                     &p_sys->i_rate,
                                                     &p_sys->i_frame_length,
                                                     &p_sys->i_header_size );
+                if( p_sys->i_frame_size > 0 ){
+                     p_sys->adts_channels = p_sys->i_channels;
+                     p_sys->adts_rate = p_sys->i_rate;
+                }
+
+#if 0	/* only for debug */
+                {
+                    uint8_t  tmpbuf[9 + 6];
+                    uint8_t*  bp = tmpbuf;
+                    int  ltmp;
+                    if( block_PeekBytes( &p_sys->bytestream, tmpbuf,
+                            sizeof(tmpbuf) ) == VLC_SUCCESS ){
+                        ltmp = ((bp[3] & 0x03) << 11) | (bp[4] << 3) | ((bp[5] >> 5) & 0x7);
+                        msg_Dbg( p_dec,
+                            "ADTS dump (%d): %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", ltmp,
+                            tmpbuf[0], tmpbuf[1],tmpbuf[2],tmpbuf[3],tmpbuf[4],tmpbuf[5],tmpbuf[6],tmpbuf[7],
+                            tmpbuf[8],tmpbuf[9],tmpbuf[10],tmpbuf[11],tmpbuf[12],tmpbuf[13],tmpbuf[14] );
+                        if( block_PeekOffsetBytes( &p_sys->bytestream, ltmp, tmpbuf, sizeof(tmpbuf) ) == VLC_SUCCESS ){
+                            msg_Dbg( p_dec,
+                                "ADTS dump next: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X",
+                                tmpbuf[0], tmpbuf[1],tmpbuf[2],tmpbuf[3],tmpbuf[4],tmpbuf[5],tmpbuf[6],tmpbuf[7],
+                                tmpbuf[8],tmpbuf[9],tmpbuf[10],tmpbuf[11],tmpbuf[12],tmpbuf[13],tmpbuf[14] );
+                        }
+                    }
+                }
+#endif
             }
             else
             {
@@ -1088,6 +1135,7 @@
                 msg_Dbg( p_dec, "emulated sync word" );
                 block_SkipByte( &p_sys->bytestream );
                 p_sys->i_state = STATE_NOSYNC;
+                p_sys->adts_rate = p_sys->adts_channels = -1;
                 break;
             }
 
@@ -1099,6 +1147,7 @@
             if( p_sys->bytestream.p_block == NULL )
             {
                 p_sys->i_state = STATE_NOSYNC;
+                p_sys->adts_rate = p_sys->adts_channels = -1;
                 block_BytestreamFlush( &p_sys->bytestream );
                 return NULL;
             }
@@ -1121,6 +1170,7 @@
                 msg_Dbg( p_dec, "emulated sync word "
                          "(no sync on following frame)" );
                 p_sys->i_state = STATE_NOSYNC;
+                p_sys->adts_rate = p_sys->adts_channels = -1;
                 block_SkipByte( &p_sys->bytestream );
                 break;
             }
@@ -1173,6 +1223,7 @@
                     block_Release( p_out_buffer );
                     p_out_buffer = NULL;
                     p_sys->i_state = STATE_NOSYNC;
+                    p_sys->adts_rate = p_sys->adts_channels = -1;
                     break;
                 }
             }
@@ -1200,7 +1251,8 @@
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
 
-    if( p_dec->fmt_out.audio.i_rate != p_sys->i_rate )
+    if( (p_dec->fmt_out.audio.i_rate != p_sys->i_rate) ||
+            (p_dec->fmt_out.audio.i_channels != p_sys->i_channels) )
     {
         msg_Info( p_dec, "AAC channels: %d samplerate: %d",
                   p_sys->i_channels, p_sys->i_rate );
diff -Nru vlc-1.1.8.orig//src/input/decoder.c vlc-1.1.8/src/input/decoder.c
--- vlc-1.1.8.orig//src/input/decoder.c	2011-03-16 20:11:09.000000000 +0900
+++ vlc-1.1.8/src/input/decoder.c	2011-04-02 20:04:50.305286991 +0900
@@ -1742,8 +1742,27 @@
     while( ( p_sout_block =
                  p_dec->pf_packetize( p_dec, p_block ? &p_block : NULL ) ) )
     {
-        if( !p_owner->p_sout_input )
+#if 0
+        char  tmpstr[32];
+        form_time( tmpstr );
+        msg_Dbg( p_dec, "DecoderProcessSout-1: %s", tmpstr );
+#endif
+        if( p_dec->fmt_in.i_cat == AUDIO_ES ){
+            msg_Dbg( p_dec, "pass fmt_out (%d,%d)",
+                p_dec->fmt_out.audio.i_channels, p_dec->fmt_out.audio.i_rate );
+        }
+        if( !p_owner->p_sout_input ||
+                ((p_dec->fmt_out.i_cat == AUDIO_ES) &&
+                  ((p_dec->fmt_out.audio.i_channels != p_owner->sout.audio.i_channels) ||
+                   (p_dec->fmt_out.audio.i_rate != p_owner->sout.audio.i_rate) ||
+                   (p_dec->fmt_out.i_extra != p_owner->sout.i_extra) ||
+                   ((p_dec->fmt_out.i_extra > 0) && memcmp( p_dec->fmt_out.p_extra, p_owner->sout.p_extra, p_dec->fmt_out.i_extra )))) )
         {
+            if( p_owner->p_sout_input ){
+                sout_InputDelete( p_owner->p_sout_input );
+                es_format_Clean( &p_owner->sout );
+            }
+
             es_format_Copy( &p_owner->sout, &p_dec->fmt_out );
 
             p_owner->sout.i_group = p_dec->fmt_in.i_group;
@@ -1853,7 +1872,14 @@
         while( (p_packetized_block =
                 p_packetizer->pf_packetize( p_packetizer, p_block ? &p_block : NULL )) )
         {
-            if( p_packetizer->fmt_out.i_extra && !p_dec->fmt_in.i_extra )
+            /*
+             * FIXME: Should we use "es_format_IsSimilar()" ?,
+             * to compare decoder's fmt_in and packetizer's fmt_out.
+             */
+            if( (p_packetizer->fmt_out.audio.i_channels != p_dec->fmt_in.audio.i_channels) ||
+                (p_packetizer->fmt_out.audio.i_rate != p_dec->fmt_in.audio.i_rate) ||
+                (p_packetizer->fmt_out.i_extra != p_dec->fmt_in.i_extra) ||
+                ((p_packetizer->fmt_out.i_extra > 0) && memcmp( p_packetizer->fmt_out.p_extra, p_dec->fmt_in.p_extra, p_packetizer->fmt_out.i_extra )) )
             {
                 es_format_Clean( &p_dec->fmt_in );
                 es_format_Copy( &p_dec->fmt_in, &p_packetizer->fmt_out );
