]> git.sesse.net Git - vlc/blobdiff - modules/packetizer/mpeg4audio.c
Zvbi: kill a warning
[vlc] / modules / packetizer / mpeg4audio.c
index 6f238634aebfbb28a960b01978fa8c4e9becd277..3e4561c09d213a64031992f729c671bed66e824c 100644 (file)
 # include "config.h"
 #endif
 
 # include "config.h"
 #endif
 
-#include <vlc/vlc.h>
+#include <vlc_common.h>
+#include <vlc_plugin.h>
 #include <vlc_aout.h>
 #include <vlc_codec.h>
 #include <vlc_block.h>
 #include <vlc_aout.h>
 #include <vlc_codec.h>
 #include <vlc_block.h>
-#include <vlc_sout.h>
-#include <vlc_codecs.h>
-#include <vlc_input.h>
 #include <vlc_bits.h>
 
 #include <vlc_bits.h>
 
-#include "vlc_block_helper.h"
+#include <vlc_block_helper.h>
+
+#include <assert.h>
 
 /* AAC Config in ES:
  *
 
 /* AAC Config in ES:
  *
@@ -63,6 +63,7 @@ typedef struct
     int i_samplerate;
     int i_channel;
     int i_sbr;          // 0: no sbr, 1: sbr, -1: unknown
     int i_samplerate;
     int i_channel;
     int i_sbr;          // 0: no sbr, 1: sbr, -1: unknown
+    int i_ps;           // 0: no ps,  1: ps,  -1: unknown
 
     struct
     {
 
     struct
     {
@@ -125,7 +126,7 @@ struct decoder_sys_t
     /*
      * Common properties
      */
     /*
      * Common properties
      */
-    audio_date_t end_date;
+    date_t  end_date;
     mtime_t i_pts;
 
     int i_frame_size;
     mtime_t i_pts;
 
     int i_frame_size;
@@ -135,12 +136,11 @@ struct decoder_sys_t
     int i_input_rate;
 
     /* LOAS */
     int i_input_rate;
 
     /* LOAS */
-    vlc_bool_t b_latm_cfg;
+    bool b_latm_cfg;
     latm_mux_t latm;
 };
 
 enum {
     latm_mux_t latm;
 };
 
 enum {
-
     STATE_NOSYNC,
     STATE_SYNC,
     STATE_HEADER,
     STATE_NOSYNC,
     STATE_SYNC,
     STATE_HEADER,
@@ -177,13 +177,13 @@ static block_t *PacketizeStreamBlock( decoder_t *, block_t ** );
 /*****************************************************************************
  * Module descriptor
  *****************************************************************************/
 /*****************************************************************************
  * Module descriptor
  *****************************************************************************/
-vlc_module_begin();
-    set_category( CAT_SOUT );
-    set_subcategory( SUBCAT_SOUT_PACKETIZER );
-    set_description( _("MPEG4 audio packetizer") );
-    set_capability( "packetizer", 50 );
-    set_callbacks( OpenPacketizer, ClosePacketizer );
-vlc_module_end();
+vlc_module_begin ()
+    set_category( CAT_SOUT )
+    set_subcategory( SUBCAT_SOUT_PACKETIZER )
+    set_description( N_("MPEG4 audio packetizer") )
+    set_capability( "packetizer", 50 )
+    set_callbacks( OpenPacketizer, ClosePacketizer )
+vlc_module_end ()
 
 /*****************************************************************************
  * OpenPacketizer: probe the packetizer and return score
 
 /*****************************************************************************
  * OpenPacketizer: probe the packetizer and return score
@@ -193,7 +193,7 @@ static int OpenPacketizer( vlc_object_t *p_this )
     decoder_t *p_dec = (decoder_t*)p_this;
     decoder_sys_t *p_sys;
 
     decoder_t *p_dec = (decoder_t*)p_this;
     decoder_sys_t *p_sys;
 
-    if( p_dec->fmt_in.i_codec != VLC_FOURCC( 'm', 'p', '4', 'a' ) )
+    if( p_dec->fmt_in.i_codec != VLC_CODEC_MP4A )
     {
         return VLC_EGENERIC;
     }
     {
         return VLC_EGENERIC;
     }
@@ -201,21 +201,17 @@ static int OpenPacketizer( vlc_object_t *p_this )
     /* Allocate the memory needed to store the decoder's structure */
     if( ( p_dec->p_sys = p_sys =
           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
     /* Allocate the memory needed to store the decoder's structure */
     if( ( p_dec->p_sys = p_sys =
           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
-    {
-        msg_Err( p_dec, "out of memory" );
-        return VLC_EGENERIC;
-    }
+        return VLC_ENOMEM;
 
     /* Misc init */
     p_sys->i_state = STATE_NOSYNC;
 
     /* Misc init */
     p_sys->i_state = STATE_NOSYNC;
-    aout_DateSet( &p_sys->end_date, 0 );
-    p_sys->bytestream = block_BytestreamInit( p_dec );
-    p_sys->i_input_rate = INPUT_RATE_DEFAULT;
-    p_sys->b_latm_cfg = VLC_FALSE;
+    date_Set( &p_sys->end_date, 0 );
+    p_sys->bytestream = block_BytestreamInit();
+    p_sys->b_latm_cfg = false;
 
     /* Set output properties */
     p_dec->fmt_out.i_cat = AUDIO_ES;
 
     /* Set output properties */
     p_dec->fmt_out.i_cat = AUDIO_ES;
-    p_dec->fmt_out.i_codec = VLC_FOURCC('m','p','4','a');
+    p_dec->fmt_out.i_codec = VLC_CODEC_MP4A;
 
     msg_Dbg( p_dec, "running MPEG4 audio packetizer" );
 
 
     msg_Dbg( p_dec, "running MPEG4 audio packetizer" );
 
@@ -240,15 +236,22 @@ static int OpenPacketizer( vlc_object_t *p_this )
                 (( p_config[4] >> 2 ) & 0x01) ? 960 : 1024;
         }
 
                 (( p_config[4] >> 2 ) & 0x01) ? 960 : 1024;
         }
 
+        p_dec->fmt_out.audio.i_channels =
+            (p_config[i_index == 0x0f ? 4 : 1] >> 3) & 0x0f;
+
         msg_Dbg( p_dec, "AAC %dHz %d samples/frame",
                  p_dec->fmt_out.audio.i_rate,
                  p_dec->fmt_out.audio.i_frame_length );
 
         msg_Dbg( p_dec, "AAC %dHz %d samples/frame",
                  p_dec->fmt_out.audio.i_rate,
                  p_dec->fmt_out.audio.i_frame_length );
 
-        aout_DateInit( &p_sys->end_date, p_dec->fmt_out.audio.i_rate );
+        date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 );
 
 
-        p_dec->fmt_out.audio.i_channels = p_dec->fmt_in.audio.i_channels;
         p_dec->fmt_out.i_extra = p_dec->fmt_in.i_extra;
         p_dec->fmt_out.p_extra = malloc( p_dec->fmt_in.i_extra );
         p_dec->fmt_out.i_extra = p_dec->fmt_in.i_extra;
         p_dec->fmt_out.p_extra = malloc( p_dec->fmt_in.i_extra );
+        if( !p_dec->fmt_out.p_extra )
+        {
+            p_dec->fmt_out.i_extra = 0;
+            return VLC_ENOMEM;
+        }
         memcpy( p_dec->fmt_out.p_extra, p_dec->fmt_in.p_extra,
                 p_dec->fmt_in.i_extra );
 
         memcpy( p_dec->fmt_out.p_extra, p_dec->fmt_in.p_extra,
                 p_dec->fmt_in.i_extra );
 
@@ -260,7 +263,7 @@ static int OpenPacketizer( vlc_object_t *p_this )
     {
         msg_Dbg( p_dec, "no decoder specific info, must be an ADTS or LOAS stream" );
 
     {
         msg_Dbg( p_dec, "no decoder specific info, must be an ADTS or LOAS stream" );
 
-        aout_DateInit( &p_sys->end_date, p_dec->fmt_in.audio.i_rate );
+        date_Init( &p_sys->end_date, p_dec->fmt_in.audio.i_rate, 1 );
 
         /* We will try to create a AAC Config from adts/loas */
         p_dec->fmt_out.i_extra = 0;
 
         /* We will try to create a AAC Config from adts/loas */
         p_dec->fmt_out.i_extra = 0;
@@ -288,7 +291,7 @@ static block_t *PacketizeRawBlock( decoder_t *p_dec, block_t **pp_block )
 
     if( (*pp_block)->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
     {
 
     if( (*pp_block)->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
     {
-        //aout_DateSet( &p_sys->end_date, 0 );
+        date_Set( &p_sys->end_date, 0 );
         block_Release( *pp_block );
         return NULL;
     }
         block_Release( *pp_block );
         return NULL;
     }
@@ -296,22 +299,22 @@ static block_t *PacketizeRawBlock( decoder_t *p_dec, block_t **pp_block )
     p_block = *pp_block;
     *pp_block = NULL; /* Don't reuse this block */
 
     p_block = *pp_block;
     *pp_block = NULL; /* Don't reuse this block */
 
-    if( !aout_DateGet( &p_sys->end_date ) && !p_block->i_pts )
+    if( !date_Get( &p_sys->end_date ) && p_block->i_pts <= VLC_TS_INVALID )
     {
         /* We've just started the stream, wait for the first PTS. */
         block_Release( p_block );
         return NULL;
     }
     {
         /* We've just started the stream, wait for the first PTS. */
         block_Release( p_block );
         return NULL;
     }
-    else if( p_block->i_pts != 0 &&
-             p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
+    else if( p_block->i_pts > VLC_TS_INVALID &&
+             p_block->i_pts != date_Get( &p_sys->end_date ) )
     {
     {
-        aout_DateSet( &p_sys->end_date, p_block->i_pts );
+        date_Set( &p_sys->end_date, p_block->i_pts );
     }
 
     }
 
-    p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
+    p_block->i_pts = p_block->i_dts = date_Get( &p_sys->end_date );
 
 
-    p_block->i_length = aout_DateIncrement( &p_sys->end_date,
-        p_dec->fmt_out.audio.i_frame_length * p_sys->i_input_rate / INPUT_RATE_DEFAULT ) - p_block->i_pts;
+    p_block->i_length = date_Increment( &p_sys->end_date,
+        p_dec->fmt_out.audio.i_frame_length ) - p_block->i_pts;
 
     return p_block;
 }
 
     return p_block;
 }
@@ -319,41 +322,93 @@ static block_t *PacketizeRawBlock( decoder_t *p_dec, block_t **pp_block )
 /****************************************************************************
  * ADTS helpers
  ****************************************************************************/
 /****************************************************************************
  * ADTS helpers
  ****************************************************************************/
-static int ADTSSyncInfo( decoder_t * p_dec, const byte_t * p_buf,
+static int ADTSSyncInfo( decoder_t * p_dec, const uint8_t * p_buf,
                          unsigned int * pi_channels,
                          unsigned int * pi_sample_rate,
                          unsigned int * pi_frame_length,
                          unsigned int * pi_header_size )
 {
                          unsigned int * pi_channels,
                          unsigned int * pi_sample_rate,
                          unsigned int * pi_frame_length,
                          unsigned int * pi_header_size )
 {
-    int i_id, i_profile, i_sample_rate_idx, i_frame_size;
-    vlc_bool_t b_crc;
+    int i_profile, i_sample_rate_idx, i_frame_size;
+    bool b_crc;
 
     /* Fixed header between frames */
 
     /* Fixed header between frames */
-    i_id = ( (p_buf[1] >> 3) & 0x01 ) ? 2 : 4;
+    //int i_id = ( (p_buf[1] >> 3) & 0x01) ? 2 : 4; /* MPEG-2 or 4 */
     b_crc = !(p_buf[1] & 0x01);
     i_profile = p_buf[2] >> 6;
     i_sample_rate_idx = (p_buf[2] >> 2) & 0x0f;
     *pi_sample_rate = pi_sample_rates[i_sample_rate_idx];
     b_crc = !(p_buf[1] & 0x01);
     i_profile = p_buf[2] >> 6;
     i_sample_rate_idx = (p_buf[2] >> 2) & 0x0f;
     *pi_sample_rate = pi_sample_rates[i_sample_rate_idx];
+    //private_bit = (p_buf[2] >> 1) & 0x01;
     *pi_channels = ((p_buf[2] & 0x01) << 2) | ((p_buf[3] >> 6) & 0x03);
     *pi_channels = ((p_buf[2] & 0x01) << 2) | ((p_buf[3] >> 6) & 0x03);
+    //original_copy = (p_buf[3] >> 5) & 0x01;
+    //home = (p_buf[3] >> 4) & 0x01;
 
     /* Variable header */
 
     /* Variable header */
+    //copyright_id_bit = (p_buf[3] >> 3) & 0x01;
+    //copyright_id_start = (p_buf[3] >> 2) & 0x01;
     i_frame_size = ((p_buf[3] & 0x03) << 11) | (p_buf[4] << 3) |
     i_frame_size = ((p_buf[3] & 0x03) << 11) | (p_buf[4] << 3) |
-                   ((p_buf[5] >> 5) & 0x7);
-    //i_raw_blocks_in_frame = (p_buf[6] & 0x02) + 1;
+                   ((p_buf[5] >> 5) /*& 0x7*/);
+    //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 )
     {
 
     if( !*pi_sample_rate || !*pi_channels || !i_frame_size )
     {
+        msg_Warn( p_dec, "Invalid ADTS header" );
         return 0;
     }
 
         return 0;
     }
 
-    /* Fixme */
     *pi_frame_length = 1024;
 
     *pi_frame_length = 1024;
 
+    if( i_raw_blocks_in_frame == 0 )
+    {
+        if( b_crc )
+        {
+            msg_Warn( p_dec, "ADTS CRC not supported" );
+            //uint16_t crc = (p_buf[7] << 8) | p_buf[8];
+        }
+    }
+    else
+    {
+        msg_Err( p_dec, "Multiple blocks per frame in ADTS not supported" );
+        return 0;
+#if 0
+        int i;
+        const uint8_t *p_pos = p_buf + 7;
+        uint16_t crc_block;
+        uint16_t i_block_pos[3];
+        if( b_crc )
+        {
+            for( i = 0 ; i < i_raw_blocks_in_frame ; i++ )
+            {   /* the 1st block's position is known ... */
+                i_block_pos[i] = (*p_pos << 8) | *(p_pos+1);
+                p_pos += 2;
+            }
+            crc_block = (*p_pos << 8) | *(p_pos+1);
+            p_pos += 2;
+        }
+        for( i = 0 ; i <= i_raw_blocks_in_frame ; i++ )
+        {
+            //read 1 block
+            if( b_crc )
+            {
+                msg_Err( p_dec, "ADTS CRC not supported" );
+                //uint16_t crc = (*p_pos << 8) | *(p_pos+1);
+                //p_pos += 2;
+            }
+        }
+#endif
+    }
+
+
     /* Build the decoder specific info header */
     if( !p_dec->fmt_out.i_extra )
     {
     /* Build the decoder specific info header */
     if( !p_dec->fmt_out.i_extra )
     {
-        p_dec->fmt_out.i_extra = 2;
         p_dec->fmt_out.p_extra = malloc( 2 );
         p_dec->fmt_out.p_extra = malloc( 2 );
+        if( !p_dec->fmt_out.p_extra )
+        {
+            p_dec->fmt_out.i_extra = 0;
+            return 0;
+        }
+        p_dec->fmt_out.i_extra = 2;
         ((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] =
         ((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] =
@@ -365,14 +420,16 @@ static int ADTSSyncInfo( decoder_t * p_dec, const byte_t * p_buf,
 
     return i_frame_size - *pi_header_size;
 }
 
     return i_frame_size - *pi_header_size;
 }
+
 /****************************************************************************
  * LOAS helpers
  ****************************************************************************/
 /****************************************************************************
  * LOAS helpers
  ****************************************************************************/
-static int LOASSyncInfo( decoder_t *p_dec, uint8_t p_header[LOAS_HEADER_SIZE], unsigned int *pi_header_size )
+static int LOASSyncInfo( uint8_t p_header[LOAS_HEADER_SIZE], unsigned int *pi_header_size )
 {
     *pi_header_size = 3;
     return ( ( p_header[1] & 0x1f ) << 8 ) + p_header[2];
 }
 {
     *pi_header_size = 3;
     return ( ( p_header[1] & 0x1f ) << 8 ) + p_header[2];
 }
+
 static int Mpeg4GAProgramConfigElement( bs_t *s )
 {
     /* TODO compute channels count ? */
 static int Mpeg4GAProgramConfigElement( bs_t *s )
 {
     /* TODO compute channels count ? */
@@ -405,6 +462,7 @@ static int Mpeg4GAProgramConfigElement( bs_t *s )
     bs_skip( s, i_comment * 8 );
     return 0;
 }
     bs_skip( s, i_comment * 8 );
     return 0;
 }
+
 static int Mpeg4GASpecificConfig( mpeg4_cfg_t *p_cfg, bs_t *s )
 {
     p_cfg->i_frame_length = bs_read1(s) ? 960 : 1024;
 static int Mpeg4GASpecificConfig( mpeg4_cfg_t *p_cfg, bs_t *s )
 {
     p_cfg->i_frame_length = bs_read1(s) ? 960 : 1024;
@@ -436,13 +494,15 @@ static int Mpeg4GASpecificConfig( mpeg4_cfg_t *p_cfg, bs_t *s )
     }
     return 0;
 }
     }
     return 0;
 }
+
 static int Mpeg4ReadAudioObjectType( bs_t *s )
 {
     int i_type = bs_read( s, 5 );
 static int Mpeg4ReadAudioObjectType( bs_t *s )
 {
     int i_type = bs_read( s, 5 );
-    if( i_type == 0x1f )
-        i_type += bs_read( s, 6 );
+    if( i_type == 31 )
+        i_type = 32 + bs_read( s, 6 );
     return i_type;
 }
     return i_type;
 }
+
 static int Mpeg4ReadAudioSamplerate( bs_t *s )
 {
     int i_index = bs_read( s, 4 );
 static int Mpeg4ReadAudioSamplerate( bs_t *s )
 {
     int i_index = bs_read( s, 4 );
@@ -450,6 +510,7 @@ static int Mpeg4ReadAudioSamplerate( bs_t *s )
         return pi_sample_rates[i_index];
     return bs_read( s, 24 );
 }
         return pi_sample_rates[i_index];
     return bs_read( s, 24 );
 }
+
 static int Mpeg4ReadAudioSpecificInfo( mpeg4_cfg_t *p_cfg, int *pi_extra, uint8_t *p_extra, bs_t *s, int i_max_size )
 {
 #if 0
 static int Mpeg4ReadAudioSpecificInfo( mpeg4_cfg_t *p_cfg, int *pi_extra, uint8_t *p_extra, bs_t *s, int i_max_size )
 {
 #if 0
@@ -467,7 +528,7 @@ static int Mpeg4ReadAudioSpecificInfo( mpeg4_cfg_t *p_cfg, int *pi_extra, uint8_
         "ER AAC LTP", "ER AAC Scalable", "ER TwinVQ", "ER BSAC", "ER AAC LD",
         "ER CELP", "ER HVXC", "ER HILN", "ER Parametric",
         "SSC",
         "ER AAC LTP", "ER AAC Scalable", "ER TwinVQ", "ER BSAC", "ER AAC LD",
         "ER CELP", "ER HVXC", "ER HILN", "ER Parametric",
         "SSC",
-        "Reserved", "Reserved", "Escape",
+        "PS", "Reserved", "Escape",
         "Layer 1", "Layer 2", "Layer 3",
         "DST",
     };
         "Layer 1", "Layer 2", "Layer 3",
         "DST",
     };
@@ -479,7 +540,7 @@ static int Mpeg4ReadAudioSpecificInfo( mpeg4_cfg_t *p_cfg, int *pi_extra, uint8_
 
     memset( p_cfg, 0, sizeof(*p_cfg) );
     *pi_extra = 0;
 
     memset( p_cfg, 0, sizeof(*p_cfg) );
     *pi_extra = 0;
-    
+
     p_cfg->i_object_type = Mpeg4ReadAudioObjectType( s );
     p_cfg->i_samplerate = Mpeg4ReadAudioSamplerate( s );
 
     p_cfg->i_object_type = Mpeg4ReadAudioObjectType( s );
     p_cfg->i_samplerate = Mpeg4ReadAudioSamplerate( s );
 
@@ -490,12 +551,15 @@ static int Mpeg4ReadAudioSpecificInfo( mpeg4_cfg_t *p_cfg, int *pi_extra, uint8_
         p_cfg->i_channel = -1;
 
     p_cfg->i_sbr = -1;
         p_cfg->i_channel = -1;
 
     p_cfg->i_sbr = -1;
+    p_cfg->i_ps  = -1;
     p_cfg->extension.i_object_type = 0;
     p_cfg->extension.i_samplerate = 0;
     p_cfg->extension.i_object_type = 0;
     p_cfg->extension.i_samplerate = 0;
-    if( p_cfg->i_object_type == 5 )
+    if( p_cfg->i_object_type == 5 || p_cfg->i_object_type == 29 )
     {
         p_cfg->i_sbr = 1;
     {
         p_cfg->i_sbr = 1;
-        p_cfg->extension.i_object_type = p_cfg->i_object_type;
+        if( p_cfg->i_object_type == 29 )
+           p_cfg->i_ps = 1;
+        p_cfg->extension.i_object_type = 5;
         p_cfg->extension.i_samplerate = Mpeg4ReadAudioSamplerate( s );
 
         p_cfg->i_object_type = Mpeg4ReadAudioObjectType( s );
         p_cfg->extension.i_samplerate = Mpeg4ReadAudioSamplerate( s );
 
         p_cfg->i_object_type = Mpeg4ReadAudioObjectType( s );
@@ -538,6 +602,9 @@ static int Mpeg4ReadAudioSpecificInfo( mpeg4_cfg_t *p_cfg, int *pi_extra, uint8_
     case 35:
         // DSTSpecificConfig();
         break;
     case 35:
         // DSTSpecificConfig();
         break;
+    case 36:
+        // ALSSpecificConfig();
+        break;
     default:
         // error
         break;
     default:
         // error
         break;
@@ -565,7 +632,8 @@ static int Mpeg4ReadAudioSpecificInfo( mpeg4_cfg_t *p_cfg, int *pi_extra, uint8_
     default:
         break;
     }
     default:
         break;
     }
-    if( p_cfg->extension.i_object_type != 5 && i_max_size > 0 && i_max_size - (bs_pos(s) - i_pos_start) >= 16 && 
+
+    if( p_cfg->extension.i_object_type != 5 && i_max_size > 0 && i_max_size - (bs_pos(s) - i_pos_start) >= 16 &&
         bs_read( s, 11 ) == 0x2b7 )
     {
         p_cfg->extension.i_object_type = Mpeg4ReadAudioObjectType( s );
         bs_read( s, 11 ) == 0x2b7 )
     {
         p_cfg->extension.i_object_type = Mpeg4ReadAudioObjectType( s );
@@ -573,7 +641,13 @@ static int Mpeg4ReadAudioSpecificInfo( mpeg4_cfg_t *p_cfg, int *pi_extra, uint8_
         {
             p_cfg->i_sbr  = bs_read1( s );
             if( p_cfg->i_sbr == 1 )
         {
             p_cfg->i_sbr  = bs_read1( s );
             if( p_cfg->i_sbr == 1 )
+            {
                 p_cfg->extension.i_samplerate = Mpeg4ReadAudioSamplerate( s );
                 p_cfg->extension.i_samplerate = Mpeg4ReadAudioSamplerate( s );
+                if( i_max_size > 0 && i_max_size - (bs_pos(s) - i_pos_start) >= 12 && bs_read( s, 11 ) == 0x548 )
+                {
+                   p_cfg->i_ps = bs_read1( s );
+                }
+            }
         }
     }
 
         }
     }
 
@@ -582,8 +656,8 @@ static int Mpeg4ReadAudioSpecificInfo( mpeg4_cfg_t *p_cfg, int *pi_extra, uint8_
 
     i_bits = bs_pos(s) - i_pos_start;
 
 
     i_bits = bs_pos(s) - i_pos_start;
 
-    *pi_extra = ( i_bits + 7 ) / 8;
-    for( i = 0; i < __MIN( LATM_MAX_EXTRA_SIZE, *pi_extra ); i++ )
+    *pi_extra = __MIN( ( i_bits + 7 ) / 8, LATM_MAX_EXTRA_SIZE );
+    for( i = 0; i < *pi_extra; i++ )
     {
         const int i_read = __MIN( 8, i_bits - 8*i );
         p_extra[i] = bs_read( &s_sav, i_read ) << (8-i_read);
     {
         const int i_read = __MIN( 8, i_bits - 8*i );
         p_extra[i] = bs_read( &s_sav, i_read ) << (8-i_read);
@@ -639,13 +713,13 @@ static int LatmReadStreamMuxConfiguration( latm_mux_t *m, bs_t *s )
         for( i_layer = 0; i_layer < m->pi_layers[i_program]; i_layer++ )
         {
             latm_stream_t *st = &m->stream[m->i_streams];
         for( i_layer = 0; i_layer < m->pi_layers[i_program]; i_layer++ )
         {
             latm_stream_t *st = &m->stream[m->i_streams];
-            vlc_bool_t b_previous_cfg;
+            bool b_previous_cfg;
 
             m->pi_stream[i_program][i_layer] = m->i_streams;
             st->i_program = i_program;
             st->i_layer = i_layer;
 
 
             m->pi_stream[i_program][i_layer] = m->i_streams;
             st->i_program = i_program;
             st->i_layer = i_layer;
 
-            b_previous_cfg = VLC_FALSE;
+            b_previous_cfg = false;
             if( i_program != 0 || i_layer != 0 )
                 b_previous_cfg = bs_read1( s );
 
             if( i_program != 0 || i_layer != 0 )
                 b_previous_cfg = bs_read1( s );
 
@@ -733,7 +807,8 @@ static int LOASParse( decoder_t *p_dec, uint8_t *p_buffer, int i_buffer )
     /* Read the stream mux configuration if present */
     if( !bs_read1( &s ) )
     {
     /* Read the stream mux configuration if present */
     if( !bs_read1( &s ) )
     {
-        if( !LatmReadStreamMuxConfiguration( &p_sys->latm, &s ) && p_sys->latm.i_streams > 0 )
+        if( !LatmReadStreamMuxConfiguration( &p_sys->latm, &s ) &&
+            p_sys->latm.i_streams > 0 )
         {
             const latm_stream_t *st = &p_sys->latm.stream[0];
 
         {
             const latm_stream_t *st = &p_sys->latm.stream[0];
 
@@ -746,17 +821,22 @@ static int LOASParse( decoder_t *p_dec, uint8_t *p_buffer, int i_buffer )
             {
                 p_dec->fmt_out.i_extra = st->i_extra;
                 p_dec->fmt_out.p_extra = malloc( st->i_extra );
             {
                 p_dec->fmt_out.i_extra = st->i_extra;
                 p_dec->fmt_out.p_extra = malloc( st->i_extra );
+                if( !p_dec->fmt_out.p_extra )
+                {
+                    p_dec->fmt_out.i_extra = 0;
+                    return 0;
+                }
                 memcpy( p_dec->fmt_out.p_extra, st->extra, st->i_extra );
             }
 
                 memcpy( p_dec->fmt_out.p_extra, st->extra, st->i_extra );
             }
 
-            p_sys->b_latm_cfg = VLC_TRUE;
+            p_sys->b_latm_cfg = true;
         }
     }
     /* Wait for the configuration */
     if( !p_sys->b_latm_cfg )
         return 0;
 
         }
     }
     /* Wait for the configuration */
     if( !p_sys->b_latm_cfg )
         return 0;
 
-    /* FIXME do we need to split the subframe into independant packet ? */
+    /* FIXME do we need to split the subframe into independent packet ? */
     if( p_sys->latm.i_sub_frames > 1 )
         msg_Err( p_dec, "latm sub frames not yet supported, please send a sample" );
 
     if( p_sys->latm.i_sub_frames > 1 )
         msg_Err( p_dec, "latm sub frames not yet supported, please send a sample" );
 
@@ -789,7 +869,9 @@ static int LOASParse( decoder_t *p_dec, uint8_t *p_buffer, int i_buffer )
                     {
                         pi_payload[i_program][i_layer] = st->i_frame_length / 8; /* XXX not correct */
                     }
                     {
                         pi_payload[i_program][i_layer] = st->i_frame_length / 8; /* XXX not correct */
                     }
-                    else if( st->i_frame_length_type == 3 || st->i_frame_length_type == 5 || st->i_frame_length_type == 7 )
+                    else if( ( st->i_frame_length_type == 3 ) ||
+                             ( st->i_frame_length_type == 5 ) ||
+                             ( st->i_frame_length_type == 7 ) )
                     {
                         bs_skip( &s, 2 ); // muxSlotLengthCoded
                         pi_payload[i_program][i_layer] = 0; /* TODO */
                     {
                         bs_skip( &s, 2 ); // muxSlotLengthCoded
                         pi_payload[i_program][i_layer] = 0; /* TODO */
@@ -856,7 +938,9 @@ static int LOASParse( decoder_t *p_dec, uint8_t *p_buffer, int i_buffer )
                 {
                     pi_payload[i_program][i_layer] = st->i_frame_length / 8; /* XXX not correct */
                 }
                 {
                     pi_payload[i_program][i_layer] = st->i_frame_length / 8; /* XXX not correct */
                 }
-                else if( st->i_frame_length_type == 3 || st->i_frame_length_type == 5 || st->i_frame_length_type == 7 )
+                else if( ( st->i_frame_length_type == 3 ) ||
+                         ( st->i_frame_length_type == 5 ) ||
+                         ( st->i_frame_length_type == 7 ) )
                 {
                     bs_read( &s, 2 ); // muxSlotLengthCoded
                 }
                 {
                     bs_read( &s, 2 ); // muxSlotLengthCoded
                 }
@@ -901,23 +985,20 @@ static block_t *PacketizeStreamBlock( decoder_t *p_dec, block_t **pp_block )
         if( (*pp_block)->i_flags&BLOCK_FLAG_CORRUPTED )
         {
             p_sys->i_state = STATE_NOSYNC;
         if( (*pp_block)->i_flags&BLOCK_FLAG_CORRUPTED )
         {
             p_sys->i_state = STATE_NOSYNC;
-            block_BytestreamFlush( &p_sys->bytestream );
+            block_BytestreamEmpty( &p_sys->bytestream );
         }
         }
-        //aout_DateSet( &p_sys->end_date, 0 );
+        date_Set( &p_sys->end_date, 0 );
         block_Release( *pp_block );
         return NULL;
     }
 
         block_Release( *pp_block );
         return NULL;
     }
 
-    if( !aout_DateGet( &p_sys->end_date ) && !(*pp_block)->i_pts )
+    if( !date_Get( &p_sys->end_date ) && (*pp_block)->i_pts <= VLC_TS_INVALID )
     {
         /* We've just started the stream, wait for the first PTS. */
         block_Release( *pp_block );
         return NULL;
     }
 
     {
         /* We've just started the stream, wait for the first PTS. */
         block_Release( *pp_block );
         return NULL;
     }
 
-    if( (*pp_block)->i_rate > 0 )
-        p_sys->i_input_rate = (*pp_block)->i_rate;
-
     block_BytestreamPush( &p_sys->bytestream, *pp_block );
 
     for( ;; )
     block_BytestreamPush( &p_sys->bytestream, *pp_block );
 
     for( ;; )
@@ -961,10 +1042,10 @@ static block_t *PacketizeStreamBlock( decoder_t *p_dec, block_t **pp_block )
         case STATE_SYNC:
             /* New frame, set the Presentation Time Stamp */
             p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
         case STATE_SYNC:
             /* New frame, set the Presentation Time Stamp */
             p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
-            if( p_sys->i_pts != 0 &&
-                p_sys->i_pts != aout_DateGet( &p_sys->end_date ) )
+            if( p_sys->i_pts > VLC_TS_INVALID &&
+                p_sys->i_pts != date_Get( &p_sys->end_date ) )
             {
             {
-                aout_DateSet( &p_sys->end_date, p_sys->i_pts );
+                date_Set( &p_sys->end_date, p_sys->i_pts );
             }
             p_sys->i_state = STATE_HEADER;
             break;
             }
             p_sys->i_state = STATE_HEADER;
             break;
@@ -999,7 +1080,7 @@ static block_t *PacketizeStreamBlock( decoder_t *p_dec, block_t **pp_block )
                 }
 
                 /* Check if frame is valid and get frame info */
                 }
 
                 /* Check if frame is valid and get frame info */
-                p_sys->i_frame_size = LOASSyncInfo( p_dec, p_header, &p_sys->i_header_size );
+                p_sys->i_frame_size = LOASSyncInfo( p_header, &p_sys->i_header_size );
             }
 
             if( p_sys->i_frame_size <= 0 )
             }
 
             if( p_sys->i_frame_size <= 0 )
@@ -1015,6 +1096,12 @@ static block_t *PacketizeStreamBlock( decoder_t *p_dec, block_t **pp_block )
         case STATE_NEXT_SYNC:
             /* TODO: If p_block == NULL, flush the buffer without checking the
              * next sync word */
         case STATE_NEXT_SYNC:
             /* TODO: If p_block == NULL, flush the buffer without checking the
              * next sync word */
+            if( p_sys->bytestream.p_block == NULL )
+            {
+                p_sys->i_state = STATE_NOSYNC;
+                block_BytestreamFlush( &p_sys->bytestream );
+                return NULL;
+            }
 
             /* Check if next expected frame contains the sync word */
             if( block_PeekOffsetBytes( &p_sys->bytestream, p_sys->i_frame_size
 
             /* Check if next expected frame contains the sync word */
             if( block_PeekOffsetBytes( &p_sys->bytestream, p_sys->i_frame_size
@@ -1025,9 +1112,11 @@ static block_t *PacketizeStreamBlock( decoder_t *p_dec, block_t **pp_block )
                 return NULL;
             }
 
                 return NULL;
             }
 
-            assert( p_sys->i_type == TYPE_ADTS || p_sys->i_type == TYPE_LOAS );
-            if( ( p_sys->i_type == TYPE_ADTS && ( p_header[0] != 0xff || (p_header[1] & 0xf6) != 0xf0 ) ) ||
-                ( p_sys->i_type == TYPE_LOAS && ( p_header[0] != 0x56 || (p_header[1] & 0xe0) != 0xe0 ) ) )
+            assert( (p_sys->i_type == TYPE_ADTS) || (p_sys->i_type == TYPE_LOAS) );
+            if( ( ( p_sys->i_type == TYPE_ADTS ) &&
+                  ( p_header[0] != 0xff || (p_header[1] & 0xf6) != 0xf0 ) ) ||
+                ( ( p_sys->i_type == TYPE_LOAS ) &&
+                  ( p_header[0] != 0x56 || (p_header[1] & 0xe0) != 0xe0 ) ) )
             {
                 msg_Dbg( p_dec, "emulated sync word "
                          "(no sync on following frame)" );
             {
                 msg_Dbg( p_dec, "emulated sync word "
                          "(no sync on following frame)" );
@@ -1057,7 +1146,7 @@ static block_t *PacketizeStreamBlock( decoder_t *p_dec, block_t **pp_block )
             p_out_buffer = block_New( p_dec, p_sys->i_frame_size );
             if( !p_out_buffer )
             {
             p_out_buffer = block_New( p_dec, p_sys->i_frame_size );
             if( !p_out_buffer )
             {
-                //p_dec->b_error = VLC_TRUE;
+                //p_dec->b_error = true;
                 return NULL;
             }
             p_buf = p_out_buffer->p_buffer;
                 return NULL;
             }
             p_buf = p_out_buffer->p_buffer;
@@ -1090,7 +1179,7 @@ static block_t *PacketizeStreamBlock( decoder_t *p_dec, block_t **pp_block )
             SetupOutput( p_dec, p_out_buffer );
             /* Make sure we don't reuse the same pts twice */
             if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
             SetupOutput( p_dec, p_out_buffer );
             /* Make sure we don't reuse the same pts twice */
             if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
-                p_sys->i_pts = p_sys->bytestream.p_block->i_pts = 0;
+                p_sys->i_pts = p_sys->bytestream.p_block->i_pts = VLC_TS_INVALID;
 
             /* So p_block doesn't get re-added several times */
             *pp_block = block_BytestreamPop( &p_sys->bytestream );
 
             /* So p_block doesn't get re-added several times */
             *pp_block = block_BytestreamPop( &p_sys->bytestream );
@@ -1104,7 +1193,6 @@ static block_t *PacketizeStreamBlock( decoder_t *p_dec, block_t **pp_block )
     return NULL;
 }
 
     return NULL;
 }
 
-
 /*****************************************************************************
  * SetupBuffer:
  *****************************************************************************/
 /*****************************************************************************
  * SetupBuffer:
  *****************************************************************************/
@@ -1117,8 +1205,9 @@ static void SetupOutput( decoder_t *p_dec, block_t *p_block )
         msg_Info( p_dec, "AAC channels: %d samplerate: %d",
                   p_sys->i_channels, p_sys->i_rate );
 
         msg_Info( p_dec, "AAC channels: %d samplerate: %d",
                   p_sys->i_channels, p_sys->i_rate );
 
-        aout_DateInit( &p_sys->end_date, p_sys->i_rate );
-        aout_DateSet( &p_sys->end_date, p_sys->i_pts );
+        const mtime_t i_end_date = date_Get( &p_sys->end_date );
+        date_Init( &p_sys->end_date, p_sys->i_rate, 1 );
+        date_Set( &p_sys->end_date, i_end_date );
     }
 
     p_dec->fmt_out.audio.i_rate     = p_sys->i_rate;
     }
 
     p_dec->fmt_out.audio.i_rate     = p_sys->i_rate;
@@ -1132,11 +1221,10 @@ static void SetupOutput( decoder_t *p_dec, block_t *p_block )
         p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK;
 #endif
 
         p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK;
 #endif
 
-    p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
+    p_block->i_pts = p_block->i_dts = date_Get( &p_sys->end_date );
 
 
-    p_block->i_length = aout_DateIncrement( &p_sys->end_date,
-                            p_sys->i_frame_length * p_sys->i_input_rate / INPUT_RATE_DEFAULT ) -
-                                p_block->i_pts;
+    p_block->i_length =
+        date_Increment( &p_sys->end_date, p_sys->i_frame_length ) - p_block->i_pts;
 }
 
 /*****************************************************************************
 }
 
 /*****************************************************************************
@@ -1151,5 +1239,3 @@ static void ClosePacketizer( vlc_object_t *p_this )
 
     free( p_dec->p_sys );
 }
 
     free( p_dec->p_sys );
 }
-
-