mpeg4audio.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:38k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * mpeg4audio.c: parse and packetize an MPEG 4 audio stream
  3.  *****************************************************************************
  4.  * Copyright (C) 2001, 2002, 2006 the VideoLAN team
  5.  * $Id: e0f99d4012b03c44022dc109dc1c67d58988f02c $
  6.  *
  7.  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  8.  *          Gildas Bazin <gbazin@netcourrier.com>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 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 General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  23.  *****************************************************************************/
  24. /*****************************************************************************
  25.  * Preamble
  26.  *****************************************************************************/
  27. #ifdef HAVE_CONFIG_H
  28. # include "config.h"
  29. #endif
  30. #include <vlc_common.h>
  31. #include <vlc_plugin.h>
  32. #include <vlc_aout.h>
  33. #include <vlc_codec.h>
  34. #include <vlc_block.h>
  35. #include <vlc_bits.h>
  36. #include "vlc_block_helper.h"
  37. #include <assert.h>
  38. /* AAC Config in ES:
  39.  *
  40.  * AudioObjectType          5 bits
  41.  * samplingFrequencyIndex   4 bits
  42.  * if (samplingFrequencyIndex == 0xF)
  43.  *  samplingFrequency   24 bits
  44.  * channelConfiguration     4 bits
  45.  * GA_SpecificConfig
  46.  *  FrameLengthFlag         1 bit 1024 or 960
  47.  *  DependsOnCoreCoder      1 bit (always 0)
  48.  *  ExtensionFlag           1 bit (always 0)
  49.  */
  50. /*****************************************************************************
  51.  * decoder_sys_t : decoder descriptor
  52.  *****************************************************************************/
  53. typedef struct
  54. {
  55.     int i_object_type;
  56.     int i_samplerate;
  57.     int i_channel;
  58.     int i_sbr;          // 0: no sbr, 1: sbr, -1: unknown
  59.     int i_ps;           // 0: no ps,  1: ps,  -1: unknown
  60.     struct
  61.     {
  62.         int i_object_type;
  63.         int i_samplerate;
  64.     } extension;
  65.     /* GASpecific */
  66.     int i_frame_length;   // 1024 or 960
  67. } mpeg4_cfg_t;
  68. #define LATM_MAX_EXTRA_SIZE 64
  69. typedef struct
  70. {
  71.     int i_program;
  72.     int i_layer;
  73.     int i_frame_length_type;
  74.     int i_frame_length;         // type 1
  75.     int i_frame_length_index;   // type 3 4 5 6 7
  76.     mpeg4_cfg_t cfg;
  77.     /* Raw configuration */
  78.     int     i_extra;
  79.     uint8_t extra[LATM_MAX_EXTRA_SIZE];
  80. } latm_stream_t;
  81. #define LATM_MAX_LAYER (8)
  82. #define LATM_MAX_PROGRAM (16)
  83. typedef struct
  84. {
  85.     int b_same_time_framing;
  86.     int i_sub_frames;
  87.     int i_programs;
  88.     int pi_layers[LATM_MAX_PROGRAM];
  89.     int pi_stream[LATM_MAX_PROGRAM][LATM_MAX_LAYER];
  90.     int i_streams;
  91.     latm_stream_t stream[LATM_MAX_PROGRAM*LATM_MAX_LAYER];
  92.     int i_other_data;
  93.     int i_crc;  /* -1 if not set */
  94. } latm_mux_t;
  95. struct decoder_sys_t
  96. {
  97.     /*
  98.      * Input properties
  99.      */
  100.     int i_state;
  101.     int i_type;
  102.     block_bytestream_t bytestream;
  103.     /*
  104.      * Common properties
  105.      */
  106.     audio_date_t end_date;
  107.     mtime_t i_pts;
  108.     int i_frame_size;
  109.     unsigned int i_channels;
  110.     unsigned int i_rate, i_frame_length, i_header_size;
  111.     int i_input_rate;
  112.     /* LOAS */
  113.     bool b_latm_cfg;
  114.     latm_mux_t latm;
  115. };
  116. enum {
  117.     STATE_NOSYNC,
  118.     STATE_SYNC,
  119.     STATE_HEADER,
  120.     STATE_NEXT_SYNC,
  121.     STATE_GET_DATA,
  122.     STATE_SEND_DATA
  123. };
  124. enum {
  125.     TYPE_NONE,
  126.     TYPE_RAW,
  127.     TYPE_ADTS,
  128.     TYPE_LOAS
  129. };
  130. static const int pi_sample_rates[16] =
  131. {
  132.     96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
  133.     16000, 12000, 11025, 8000,  7350,  0,     0,     0
  134. };
  135. #define ADTS_HEADER_SIZE 9
  136. #define LOAS_HEADER_SIZE 3
  137. /****************************************************************************
  138.  * Local prototypes
  139.  ****************************************************************************/
  140. static int  OpenPacketizer( vlc_object_t * );
  141. static void ClosePacketizer( vlc_object_t * );
  142. static block_t *PacketizeRawBlock    ( decoder_t *, block_t ** );
  143. static block_t *PacketizeStreamBlock( decoder_t *, block_t ** );
  144. /*****************************************************************************
  145.  * Module descriptor
  146.  *****************************************************************************/
  147. vlc_module_begin ()
  148.     set_category( CAT_SOUT )
  149.     set_subcategory( SUBCAT_SOUT_PACKETIZER )
  150.     set_description( N_("MPEG4 audio packetizer") )
  151.     set_capability( "packetizer", 50 )
  152.     set_callbacks( OpenPacketizer, ClosePacketizer )
  153. vlc_module_end ()
  154. /*****************************************************************************
  155.  * OpenPacketizer: probe the packetizer and return score
  156.  *****************************************************************************/
  157. static int OpenPacketizer( vlc_object_t *p_this )
  158. {
  159.     decoder_t *p_dec = (decoder_t*)p_this;
  160.     decoder_sys_t *p_sys;
  161.     if( p_dec->fmt_in.i_codec != VLC_FOURCC( 'm', 'p', '4', 'a' ) )
  162.     {
  163.         return VLC_EGENERIC;
  164.     }
  165.     /* Allocate the memory needed to store the decoder's structure */
  166.     if( ( p_dec->p_sys = p_sys =
  167.           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
  168.         return VLC_ENOMEM;
  169.     /* Misc init */
  170.     p_sys->i_state = STATE_NOSYNC;
  171.     aout_DateSet( &p_sys->end_date, 0 );
  172.     p_sys->bytestream = block_BytestreamInit();
  173.     p_sys->b_latm_cfg = false;
  174.     /* Set output properties */
  175.     p_dec->fmt_out.i_cat = AUDIO_ES;
  176.     p_dec->fmt_out.i_codec = VLC_FOURCC('m','p','4','a');
  177.     msg_Dbg( p_dec, "running MPEG4 audio packetizer" );
  178.     if( p_dec->fmt_in.i_extra > 0 )
  179.     {
  180.         uint8_t *p_config = (uint8_t*)p_dec->fmt_in.p_extra;
  181.         int     i_index;
  182.         i_index = ( ( p_config[0] << 1 ) | ( p_config[1] >> 7 ) ) & 0x0f;
  183.         if( i_index != 0x0f )
  184.         {
  185.             p_dec->fmt_out.audio.i_rate = pi_sample_rates[i_index];
  186.             p_dec->fmt_out.audio.i_frame_length =
  187.                 (( p_config[1] >> 2 ) & 0x01) ? 960 : 1024;
  188.         }
  189.         else
  190.         {
  191.             p_dec->fmt_out.audio.i_rate = ( ( p_config[1] & 0x7f ) << 17 ) |
  192.                 ( p_config[2] << 9 ) | ( p_config[3] << 1 ) |
  193.                 ( p_config[4] >> 7 );
  194.             p_dec->fmt_out.audio.i_frame_length =
  195.                 (( p_config[4] >> 2 ) & 0x01) ? 960 : 1024;
  196.         }
  197.         p_dec->fmt_out.audio.i_channels =
  198.             (p_config[i_index == 0x0f ? 4 : 1] >> 3) & 0x0f;
  199.         msg_Dbg( p_dec, "AAC %dHz %d samples/frame",
  200.                  p_dec->fmt_out.audio.i_rate,
  201.                  p_dec->fmt_out.audio.i_frame_length );
  202.         aout_DateInit( &p_sys->end_date, p_dec->fmt_out.audio.i_rate );
  203.         p_dec->fmt_out.i_extra = p_dec->fmt_in.i_extra;
  204.         p_dec->fmt_out.p_extra = malloc( p_dec->fmt_in.i_extra );
  205.         if( !p_dec->fmt_out.p_extra )
  206.         {
  207.             p_dec->fmt_out.i_extra = 0;
  208.             return VLC_ENOMEM;
  209.         }
  210.         memcpy( p_dec->fmt_out.p_extra, p_dec->fmt_in.p_extra,
  211.                 p_dec->fmt_in.i_extra );
  212.         /* Set callback */
  213.         p_dec->pf_packetize = PacketizeRawBlock;
  214.         p_sys->i_type = TYPE_RAW;
  215.     }
  216.     else
  217.     {
  218.         msg_Dbg( p_dec, "no decoder specific info, must be an ADTS or LOAS stream" );
  219.         aout_DateInit( &p_sys->end_date, p_dec->fmt_in.audio.i_rate );
  220.         /* We will try to create a AAC Config from adts/loas */
  221.         p_dec->fmt_out.i_extra = 0;
  222.         p_dec->fmt_out.p_extra = NULL;
  223.         /* Set callback */
  224.         p_dec->pf_packetize = PacketizeStreamBlock;
  225.         p_sys->i_type = TYPE_NONE;
  226.     }
  227.     return VLC_SUCCESS;
  228. }
  229. /****************************************************************************
  230.  * PacketizeRawBlock: the whole thing
  231.  ****************************************************************************
  232.  * This function must be fed with complete frames.
  233.  ****************************************************************************/
  234. static block_t *PacketizeRawBlock( decoder_t *p_dec, block_t **pp_block )
  235. {
  236.     decoder_sys_t *p_sys = p_dec->p_sys;
  237.     block_t *p_block;
  238.     if( !pp_block || !*pp_block ) return NULL;
  239.     if( (*pp_block)->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
  240.     {
  241.         aout_DateSet( &p_sys->end_date, 0 );
  242.         block_Release( *pp_block );
  243.         return NULL;
  244.     }
  245.     p_block = *pp_block;
  246.     *pp_block = NULL; /* Don't reuse this block */
  247.     if( !aout_DateGet( &p_sys->end_date ) && !p_block->i_pts )
  248.     {
  249.         /* We've just started the stream, wait for the first PTS. */
  250.         block_Release( p_block );
  251.         return NULL;
  252.     }
  253.     else if( p_block->i_pts != 0 &&
  254.              p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
  255.     {
  256.         aout_DateSet( &p_sys->end_date, p_block->i_pts );
  257.     }
  258.     p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
  259.     p_block->i_length = aout_DateIncrement( &p_sys->end_date,
  260.         p_dec->fmt_out.audio.i_frame_length ) - p_block->i_pts;
  261.     return p_block;
  262. }
  263. /****************************************************************************
  264.  * ADTS helpers
  265.  ****************************************************************************/
  266. static int ADTSSyncInfo( decoder_t * p_dec, const uint8_t * p_buf,
  267.                          unsigned int * pi_channels,
  268.                          unsigned int * pi_sample_rate,
  269.                          unsigned int * pi_frame_length,
  270.                          unsigned int * pi_header_size )
  271. {
  272.     int i_profile, i_sample_rate_idx, i_frame_size;
  273.     bool b_crc;
  274.     /* Fixed header between frames */
  275.     //int i_id = ( (p_buf[1] >> 3) & 0x01) ? 2 : 4; /* MPEG-2 or 4 */
  276.     b_crc = !(p_buf[1] & 0x01);
  277.     i_profile = p_buf[2] >> 6;
  278.     i_sample_rate_idx = (p_buf[2] >> 2) & 0x0f;
  279.     *pi_sample_rate = pi_sample_rates[i_sample_rate_idx];
  280.     //private_bit = (p_buf[2] >> 1) & 0x01;
  281.     *pi_channels = ((p_buf[2] & 0x01) << 2) | ((p_buf[3] >> 6) & 0x03);
  282.     //original_copy = (p_buf[3] >> 5) & 0x01;
  283.     //home = (p_buf[3] >> 4) & 0x01;
  284.     /* Variable header */
  285.     //copyright_id_bit = (p_buf[3] >> 3) & 0x01;
  286.     //copyright_id_start = (p_buf[3] >> 2) & 0x01;
  287.     i_frame_size = ((p_buf[3] & 0x03) << 11) | (p_buf[4] << 3) |
  288.                    ((p_buf[5] >> 5) /*& 0x7*/);
  289.     //uint16_t buffer_fullness = ((p_buf[5] & 0x1f) << 6) | (p_buf[6] >> 2);
  290.     unsigned short i_raw_blocks_in_frame = p_buf[6] & 0x03;
  291.     if( !*pi_sample_rate || !*pi_channels || !i_frame_size )
  292.     {
  293.         msg_Warn( p_dec, "Invalid ADTS header" );
  294.         return 0;
  295.     }
  296.     *pi_frame_length = 1024;
  297.     if( i_raw_blocks_in_frame == 0 )
  298.     {
  299.         if( b_crc )
  300.         {
  301.             msg_Warn( p_dec, "ADTS CRC not supported" );
  302.             //uint16_t crc = (p_buf[7] << 8) | p_buf[8];
  303.         }
  304.     }
  305.     else
  306.     {
  307.         msg_Err( p_dec, "Multiple blocks per frame in ADTS not supported" );
  308.         return 0;
  309. #if 0
  310.         int i;
  311.         const uint8_t *p_pos = p_buf + 7;
  312.         uint16_t crc_block;
  313.         uint16_t i_block_pos[3];
  314.         if( b_crc )
  315.         {
  316.             for( i = 0 ; i < i_raw_blocks_in_frame ; i++ )
  317.             {   /* the 1st block's position is known ... */
  318.                 i_block_pos[i] = (*p_pos << 8) | *(p_pos+1);
  319.                 p_pos += 2;
  320.             }
  321.             crc_block = (*p_pos << 8) | *(p_pos+1);
  322.             p_pos += 2;
  323.         }
  324.         for( i = 0 ; i <= i_raw_blocks_in_frame ; i++ )
  325.         {
  326.             //read 1 block
  327.             if( b_crc )
  328.             {
  329.                 msg_Err( p_dec, "ADTS CRC not supported" );
  330.                 //uint16_t crc = (*p_pos << 8) | *(p_pos+1);
  331.                 //p_pos += 2;
  332.             }
  333.         }
  334. #endif
  335.     }
  336.     /* Build the decoder specific info header */
  337.     if( !p_dec->fmt_out.i_extra )
  338.     {
  339.         p_dec->fmt_out.p_extra = malloc( 2 );
  340.         if( !p_dec->fmt_out.p_extra )
  341.         {
  342.             p_dec->fmt_out.i_extra = 0;
  343.             return 0;
  344.         }
  345.         p_dec->fmt_out.i_extra = 2;
  346.         ((uint8_t *)p_dec->fmt_out.p_extra)[0] =
  347.             (i_profile + 1) << 3 | (i_sample_rate_idx >> 1);
  348.         ((uint8_t *)p_dec->fmt_out.p_extra)[1] =
  349.             ((i_sample_rate_idx & 0x01) << 7) | (*pi_channels <<3);
  350.     }
  351.     /* ADTS header length */
  352.     *pi_header_size = b_crc ? 9 : 7;
  353.     return i_frame_size - *pi_header_size;
  354. }
  355. /****************************************************************************
  356.  * LOAS helpers
  357.  ****************************************************************************/
  358. static int LOASSyncInfo( uint8_t p_header[LOAS_HEADER_SIZE], unsigned int *pi_header_size )
  359. {
  360.     *pi_header_size = 3;
  361.     return ( ( p_header[1] & 0x1f ) << 8 ) + p_header[2];
  362. }
  363. static int Mpeg4GAProgramConfigElement( bs_t *s )
  364. {
  365.     /* TODO compute channels count ? */
  366.     int i_tag = bs_read( s, 4 );
  367.     if( i_tag != 0x05 )
  368.         return -1;
  369.     bs_skip( s, 2 + 4 ); // object type + sampling index
  370.     int i_num_front = bs_read( s, 4 );
  371.     int i_num_side = bs_read( s, 4 );
  372.     int i_num_back = bs_read( s, 4 );
  373.     int i_num_lfe = bs_read( s, 2 );
  374.     int i_num_assoc_data = bs_read( s, 3 );
  375.     int i_num_valid_cc = bs_read( s, 4 );
  376.     if( bs_read1(s) )
  377.         bs_skip( s, 4 ); // mono downmix
  378.     if( bs_read1(s) )
  379.         bs_skip( s, 4 ); // stereo downmix
  380.     if( bs_read1(s) )
  381.         bs_skip( s, 2+1 ); // matrix downmix + pseudo_surround
  382.     bs_skip( s, i_num_front * (1+4) );
  383.     bs_skip( s, i_num_side * (1+4) );
  384.     bs_skip( s, i_num_back * (1+4) );
  385.     bs_skip( s, i_num_lfe * (4) );
  386.     bs_skip( s, i_num_assoc_data * (4) );
  387.     bs_skip( s, i_num_valid_cc * (5) );
  388.     bs_align( s );
  389.     int i_comment = bs_read( s, 8 );
  390.     bs_skip( s, i_comment * 8 );
  391.     return 0;
  392. }
  393. static int Mpeg4GASpecificConfig( mpeg4_cfg_t *p_cfg, bs_t *s )
  394. {
  395.     p_cfg->i_frame_length = bs_read1(s) ? 960 : 1024;
  396.     if( bs_read1( s ) )     // depend on core coder
  397.         bs_skip( s, 14 );   // core coder delay
  398.     int i_extension_flag = bs_read1( s );
  399.     if( p_cfg->i_channel == 0 )
  400.     {
  401.         Mpeg4GAProgramConfigElement( s );
  402.     }
  403.     if( p_cfg->i_object_type == 6 || p_cfg->i_object_type == 20 )
  404.         bs_skip( s, 3 );    // layer
  405.     if( i_extension_flag )
  406.     {
  407.         if( p_cfg->i_object_type == 22 )
  408.         {
  409.             bs_skip( s, 5 + 11 );   // numOfSubFrame + layer length
  410.         }
  411.         if( p_cfg->i_object_type == 17 || p_cfg->i_object_type == 19 ||
  412.             p_cfg->i_object_type == 20 || p_cfg->i_object_type == 23 )
  413.         {
  414.             bs_skip( s, 1+1+1 );    // ER data : section scale spectral */
  415.         }
  416.         if( bs_read1( s ) )     // extension 3
  417.             fprintf( stderr, "Mpeg4GASpecificConfig: error 1n" );
  418.     }
  419.     return 0;
  420. }
  421. static int Mpeg4ReadAudioObjectType( bs_t *s )
  422. {
  423.     int i_type = bs_read( s, 5 );
  424.     if( i_type == 31 )
  425.         i_type = 32 + bs_read( s, 6 );
  426.     return i_type;
  427. }
  428. static int Mpeg4ReadAudioSamplerate( bs_t *s )
  429. {
  430.     int i_index = bs_read( s, 4 );
  431.     if( i_index != 0x0f )
  432.         return pi_sample_rates[i_index];
  433.     return bs_read( s, 24 );
  434. }
  435. static int Mpeg4ReadAudioSpecificInfo( mpeg4_cfg_t *p_cfg, int *pi_extra, uint8_t *p_extra, bs_t *s, int i_max_size )
  436. {
  437. #if 0
  438.     static const char *ppsz_otype[] = {
  439.         "NULL",
  440.         "AAC Main", "AAC LC", "AAC SSR", "AAC LTP", "SBR", "AAC Scalable",
  441.         "TwinVQ",
  442.         "CELP", "HVXC",
  443.         "Reserved", "Reserved",
  444.         "TTSI",
  445.         "Main Synthetic", "Wavetables Synthesis", "General MIDI",
  446.         "Algorithmic Synthesis and Audio FX",
  447.         "ER AAC LC",
  448.         "Reserved",
  449.         "ER AAC LTP", "ER AAC Scalable", "ER TwinVQ", "ER BSAC", "ER AAC LD",
  450.         "ER CELP", "ER HVXC", "ER HILN", "ER Parametric",
  451.         "SSC",
  452.         "PS", "Reserved", "Escape",
  453.         "Layer 1", "Layer 2", "Layer 3",
  454.         "DST",
  455.     };
  456. #endif
  457.     const int i_pos_start = bs_pos( s );
  458.     bs_t s_sav = *s;
  459.     int i_bits;
  460.     int i;
  461.     memset( p_cfg, 0, sizeof(*p_cfg) );
  462.     *pi_extra = 0;
  463.     p_cfg->i_object_type = Mpeg4ReadAudioObjectType( s );
  464.     p_cfg->i_samplerate = Mpeg4ReadAudioSamplerate( s );
  465.     p_cfg->i_channel = bs_read( s, 4 );
  466.     if( p_cfg->i_channel == 7 )
  467.         p_cfg->i_channel = 8; // 7.1
  468.     else if( p_cfg->i_channel >= 8 )
  469.         p_cfg->i_channel = -1;
  470.     p_cfg->i_sbr = -1;
  471.     p_cfg->i_ps  = -1;
  472.     p_cfg->extension.i_object_type = 0;
  473.     p_cfg->extension.i_samplerate = 0;
  474.     if( p_cfg->i_object_type == 5 || p_cfg->i_object_type == 29 )
  475.     {
  476.         p_cfg->i_sbr = 1;
  477.         if( p_cfg->i_object_type == 29 )
  478.            p_cfg->i_ps = 1;
  479.         p_cfg->extension.i_object_type = 5;
  480.         p_cfg->extension.i_samplerate = Mpeg4ReadAudioSamplerate( s );
  481.         p_cfg->i_object_type = Mpeg4ReadAudioObjectType( s );
  482.     }
  483.     switch( p_cfg->i_object_type )
  484.     {
  485.     case 1: case 2: case 3: case 4:
  486.     case 6: case 7:
  487.     case 17: case 19: case 20: case 21: case 22: case 23:
  488.         Mpeg4GASpecificConfig( p_cfg, s );
  489.         break;
  490.     case 8:
  491.         // CelpSpecificConfig();
  492.         break;
  493.     case 9:
  494.         // HvxcSpecificConfig();
  495.         break;
  496.     case 12:
  497.         // TTSSSpecificConfig();
  498.         break;
  499.     case 13: case 14: case 15: case 16:
  500.         // StructuredAudioSpecificConfig();
  501.         break;
  502.     case 24:
  503.         // ERCelpSpecificConfig();
  504.         break;
  505.     case 25:
  506.         // ERHvxcSpecificConfig();
  507.         break;
  508.     case 26: case 27:
  509.         // ParametricSpecificConfig();
  510.         break;
  511.     case 28:
  512.         // SSCSpecificConfig();
  513.         break;
  514.     case 32: case 33: case 34:
  515.         // MPEG_1_2_SpecificConfig();
  516.         break;
  517.     case 35:
  518.         // DSTSpecificConfig();
  519.         break;
  520.     case 36:
  521.         // ALSSpecificConfig();
  522.         break;
  523.     default:
  524.         // error
  525.         break;
  526.     }
  527.     switch( p_cfg->i_object_type )
  528.     {
  529.     case 17: case 19: case 20: case 21: case 22: case 23:
  530.     case 24: case 25: case 26: case 27:
  531.     {
  532.         int epConfig = bs_read( s, 2 );
  533.         if( epConfig == 2 || epConfig == 3 )
  534.         {
  535.             //ErrorProtectionSpecificConfig();
  536.         }
  537.         if( epConfig == 3 )
  538.         {
  539.             int directMapping = bs_read1( s );
  540.             if( directMapping )
  541.             {
  542.                 // tbd ...
  543.             }
  544.         }
  545.         break;
  546.     }
  547.     default:
  548.         break;
  549.     }
  550.     if( p_cfg->extension.i_object_type != 5 && i_max_size > 0 && i_max_size - (bs_pos(s) - i_pos_start) >= 16 &&
  551.         bs_read( s, 11 ) == 0x2b7 )
  552.     {
  553.         p_cfg->extension.i_object_type = Mpeg4ReadAudioObjectType( s );
  554.         if( p_cfg->extension.i_object_type == 5 )
  555.         {
  556.             p_cfg->i_sbr  = bs_read1( s );
  557.             if( p_cfg->i_sbr == 1 )
  558.             {
  559.                 p_cfg->extension.i_samplerate = Mpeg4ReadAudioSamplerate( s );
  560.                 if( i_max_size > 0 && i_max_size - (bs_pos(s) - i_pos_start) >= 12 && bs_read( s, 11 ) == 0x548 )
  561.                 {
  562.                    p_cfg->i_ps = bs_read1( s );
  563.                 }
  564.             }
  565.         }
  566.     }
  567.     //fprintf( stderr, "Mpeg4ReadAudioSpecificInfo: t=%s(%d)f=%d c=%d sbr=%dn",
  568.     //         ppsz_otype[p_cfg->i_object_type], p_cfg->i_object_type, p_cfg->i_samplerate, p_cfg->i_channel, p_cfg->i_sbr );
  569.     i_bits = bs_pos(s) - i_pos_start;
  570.     *pi_extra = __MIN( ( i_bits + 7 ) / 8, LATM_MAX_EXTRA_SIZE );
  571.     for( i = 0; i < *pi_extra; i++ )
  572.     {
  573.         const int i_read = __MIN( 8, i_bits - 8*i );
  574.         p_extra[i] = bs_read( &s_sav, i_read ) << (8-i_read);
  575.     }
  576.     return i_bits;
  577. }
  578. static int LatmGetValue( bs_t *s )
  579. {
  580.     int i_bytes = bs_read( s, 2 );
  581.     int v = 0;
  582.     int i;
  583.     for( i = 0; i < i_bytes; i++ )
  584.         v = (v << 8) + bs_read( s, 8 );
  585.     return v;
  586. }
  587. static int LatmReadStreamMuxConfiguration( latm_mux_t *m, bs_t *s )
  588. {
  589.     int i_mux_version;
  590.     int i_mux_versionA;
  591.     int i_program;
  592.     i_mux_version = bs_read( s, 1 );
  593.     i_mux_versionA = 0;
  594.     if( i_mux_version )
  595.         i_mux_versionA = bs_read( s, 1 );
  596.     if( i_mux_versionA != 0 ) /* support only A=0 */
  597.         return -1;
  598.     memset( m, 0, sizeof(*m) );
  599.     if( i_mux_versionA == 0 )
  600.     {
  601.         if( i_mux_version == 1 )
  602.         {
  603.             LatmGetValue(s); /* taraBufferFullness */
  604.         }
  605.     }
  606.     m->b_same_time_framing = bs_read1( s );
  607.     m->i_sub_frames = 1 + bs_read( s, 6 );
  608.     m->i_programs = 1 + bs_read( s, 4 );
  609.     for( i_program = 0; i_program < m->i_programs; i_program++ )
  610.     {
  611.         int i_layer;
  612.         m->pi_layers[i_program] = 1+bs_read( s, 3 );
  613.         for( i_layer = 0; i_layer < m->pi_layers[i_program]; i_layer++ )
  614.         {
  615.             latm_stream_t *st = &m->stream[m->i_streams];
  616.             bool b_previous_cfg;
  617.             m->pi_stream[i_program][i_layer] = m->i_streams;
  618.             st->i_program = i_program;
  619.             st->i_layer = i_layer;
  620.             b_previous_cfg = false;
  621.             if( i_program != 0 || i_layer != 0 )
  622.                 b_previous_cfg = bs_read1( s );
  623.             if( b_previous_cfg )
  624.             {
  625.                 assert( m->i_streams > 0 );
  626.                 st->cfg = m->stream[m->i_streams-1].cfg;
  627.             }
  628.             else
  629.             {
  630.                 int i_cfg_size = 0;
  631.                 if( i_mux_version == 1 )
  632.                     i_cfg_size = LatmGetValue(s);
  633.                 i_cfg_size -= Mpeg4ReadAudioSpecificInfo( &st->cfg, &st->i_extra, st->extra, s, i_cfg_size );
  634.                 if( i_cfg_size > 0 )
  635.                     bs_skip( s, i_cfg_size );
  636.             }
  637.             st->i_frame_length_type = bs_read( s, 3 );
  638.             switch( st->i_frame_length_type )
  639.             {
  640.             case 0:
  641.             {
  642.                 bs_skip( s, 8 ); /* latmBufferFullnes */
  643.                 if( !m->b_same_time_framing )
  644.                 {
  645.                     if( st->cfg.i_object_type == 6 || st->cfg.i_object_type == 20 ||
  646.                         st->cfg.i_object_type == 8 || st->cfg.i_object_type == 24 )
  647.                     {
  648.                         bs_skip( s, 6 ); /* eFrameOffset */
  649.                     }
  650.                 }
  651.                 break;
  652.             }
  653.             case 1:
  654.                 st->i_frame_length = bs_read( s, 9 );
  655.                 break;
  656.             case 3: case 4: case 5:
  657.                 st->i_frame_length_index = bs_read( s, 6 ); // celp
  658.                 break;
  659.             case 6: case 7:
  660.                 st->i_frame_length_index = bs_read( s, 1 ); // hvxc
  661.             default:
  662.                 break;
  663.             }
  664.             /* Next stream */
  665.             m->i_streams++;
  666.         }
  667.     }
  668.     /* other data */
  669.     if( bs_read1( s ) )
  670.     {
  671.         if( i_mux_version == 1 )
  672.         {
  673.             m->i_other_data = LatmGetValue( s );
  674.         }
  675.         else
  676.         {
  677.             int b_continue;
  678.             do {
  679.                 b_continue = bs_read1(s);
  680.                 m->i_other_data = (m->i_other_data << 8) + bs_read( s, 8 );
  681.             } while( b_continue );
  682.         }
  683.     }
  684.     /* crc */
  685.     m->i_crc = -1;
  686.     if( bs_read1( s ) )
  687.         m->i_crc = bs_read( s, 8 );
  688.     return 0;
  689. }
  690. static int LOASParse( decoder_t *p_dec, uint8_t *p_buffer, int i_buffer )
  691. {
  692.     decoder_sys_t *p_sys = p_dec->p_sys;
  693.     bs_t s;
  694.     int i_sub;
  695.     int i_accumulated = 0;
  696.     bs_init( &s, p_buffer, i_buffer );
  697.     /* Read the stream mux configuration if present */
  698.     if( !bs_read1( &s ) )
  699.     {
  700.         if( !LatmReadStreamMuxConfiguration( &p_sys->latm, &s ) &&
  701.             p_sys->latm.i_streams > 0 )
  702.         {
  703.             const latm_stream_t *st = &p_sys->latm.stream[0];
  704.             p_sys->i_channels = st->cfg.i_channel;
  705.             p_sys->i_rate = st->cfg.i_samplerate;
  706.             p_sys->i_frame_length = st->cfg.i_frame_length;
  707.             /* FIXME And if it changes ? */
  708.             if( !p_dec->fmt_out.i_extra && st->i_extra > 0 )
  709.             {
  710.                 p_dec->fmt_out.i_extra = st->i_extra;
  711.                 p_dec->fmt_out.p_extra = malloc( st->i_extra );
  712.                 if( !p_dec->fmt_out.p_extra )
  713.                 {
  714.                     p_dec->fmt_out.i_extra = 0;
  715.                     return 0;
  716.                 }
  717.                 memcpy( p_dec->fmt_out.p_extra, st->extra, st->i_extra );
  718.             }
  719.             p_sys->b_latm_cfg = true;
  720.         }
  721.     }
  722.     /* Wait for the configuration */
  723.     if( !p_sys->b_latm_cfg )
  724.         return 0;
  725.     /* FIXME do we need to split the subframe into independent packet ? */
  726.     if( p_sys->latm.i_sub_frames > 1 )
  727.         msg_Err( p_dec, "latm sub frames not yet supported, please send a sample" );
  728.     for( i_sub = 0; i_sub < p_sys->latm.i_sub_frames; i_sub++ )
  729.     {
  730.         int pi_payload[LATM_MAX_PROGRAM][LATM_MAX_LAYER];
  731.         if( p_sys->latm.b_same_time_framing )
  732.         {
  733.             int i_program;
  734.             /* Payload length */
  735.             for( i_program = 0; i_program < p_sys->latm.i_programs; i_program++ )
  736.             {
  737.                 int i_layer;
  738.                 for( i_layer = 0; i_layer < p_sys->latm.pi_layers[i_program]; i_layer++ )
  739.                 {
  740.                     latm_stream_t *st = &p_sys->latm.stream[p_sys->latm.pi_stream[i_program][i_layer]];
  741.                     if( st->i_frame_length_type == 0 )
  742.                     {
  743.                         int i_payload = 0;
  744.                         for( ;; )
  745.                         {
  746.                             int i_tmp = bs_read( &s, 8 );
  747.                             i_payload += i_tmp;
  748.                             if( i_tmp != 255 )
  749.                                 break;
  750.                         }
  751.                         pi_payload[i_program][i_layer] = i_payload;
  752.                     }
  753.                     else if( st->i_frame_length_type == 1 )
  754.                     {
  755.                         pi_payload[i_program][i_layer] = st->i_frame_length / 8; /* XXX not correct */
  756.                     }
  757.                     else if( ( st->i_frame_length_type == 3 ) ||
  758.                              ( st->i_frame_length_type == 5 ) ||
  759.                              ( st->i_frame_length_type == 7 ) )
  760.                     {
  761.                         bs_skip( &s, 2 ); // muxSlotLengthCoded
  762.                         pi_payload[i_program][i_layer] = 0; /* TODO */
  763.                     }
  764.                     else
  765.                     {
  766.                         pi_payload[i_program][i_layer] = 0; /* TODO */
  767.                     }
  768.                 }
  769.             }
  770.             /* Payload Data */
  771.             for( i_program = 0; i_program < p_sys->latm.i_programs; i_program++ )
  772.             {
  773.                 int i_layer;
  774.                 int i;
  775.                 for( i_layer = 0; i_layer < p_sys->latm.pi_layers[i_program]; i_layer++ )
  776.                 {
  777.                     /* XXX we only extract 1 stream */
  778.                     if( i_program != 0 || i_layer != 0 )
  779.                         break;
  780.                     if( pi_payload[i_program][i_layer] <= 0 )
  781.                         continue;
  782.                     /* FIXME that's slow (and a bit ugly to write in place) */
  783.                     for( i = 0; i < pi_payload[i_program][i_layer]; i++ )
  784.                         p_buffer[i_accumulated++] = bs_read( &s, 8 );
  785.                 }
  786.             }
  787.         }
  788.         else
  789.         {
  790.             const int i_chunks = bs_read( &s, 4 );
  791.             int pi_program[16];
  792.             int pi_layer[16];
  793.             int i_chunk;
  794.             msg_Err( p_dec, "latm without same time frameing not yet supported, please send a sample" );
  795.             for( i_chunk = 0; i_chunk < i_chunks; i_chunk++ )
  796.             {
  797.                 const int streamIndex = bs_read( &s, 4 );
  798.                 latm_stream_t *st = &p_sys->latm.stream[streamIndex];
  799.                 const int i_program = st->i_program;
  800.                 const int i_layer = st->i_layer;
  801.                 pi_program[i_chunk] = i_program;
  802.                 pi_layer[i_chunk] = i_layer;
  803.                 if( st->i_frame_length_type == 0 )
  804.                 {
  805.                     int i_payload = 0;
  806.                     for( ;; )
  807.                     {
  808.                         int i_tmp = bs_read( &s, 8 );
  809.                         i_payload += i_tmp;
  810.                         if( i_tmp != 255 )
  811.                             break;
  812.                     }
  813.                     pi_payload[i_program][i_layer] = i_payload;
  814.                     bs_skip( &s, 1 ); // auEndFlag
  815.                 }
  816.                 else if( st->i_frame_length_type == 1 )
  817.                 {
  818.                     pi_payload[i_program][i_layer] = st->i_frame_length / 8; /* XXX not correct */
  819.                 }
  820.                 else if( ( st->i_frame_length_type == 3 ) ||
  821.                          ( st->i_frame_length_type == 5 ) ||
  822.                          ( st->i_frame_length_type == 7 ) )
  823.                 {
  824.                     bs_read( &s, 2 ); // muxSlotLengthCoded
  825.                 }
  826.                 else
  827.                 {
  828.                 }
  829.             }
  830.             for( i_chunk = 0; i_chunk < i_chunks; i_chunk++ )
  831.             {
  832.                 //const int i_program = pi_program[i_chunk];
  833.                 //const int i_layer = pi_layer[i_chunk];
  834.                 /* TODO ? Payload */
  835.             }
  836.         }
  837.     }
  838.     if( p_sys->latm.i_other_data > 0 )
  839.     {
  840.         /* Other data XXX we just ignore them */
  841.     }
  842.     bs_align( &s );
  843.     return i_accumulated;
  844. }
  845. /****************************************************************************
  846.  * PacketizeStreamBlock: ADTS/LOAS packetizer
  847.  ****************************************************************************/
  848. static void SetupOutput( decoder_t *p_dec, block_t *p_block );
  849. static block_t *PacketizeStreamBlock( decoder_t *p_dec, block_t **pp_block )
  850. {
  851.     decoder_sys_t *p_sys = p_dec->p_sys;
  852.     uint8_t p_header[ADTS_HEADER_SIZE + LOAS_HEADER_SIZE];
  853.     block_t *p_out_buffer;
  854.     uint8_t *p_buf;
  855.     if( !pp_block || !*pp_block ) return NULL;
  856.     if( (*pp_block)->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
  857.     {
  858.         if( (*pp_block)->i_flags&BLOCK_FLAG_CORRUPTED )
  859.         {
  860.             p_sys->i_state = STATE_NOSYNC;
  861.             block_BytestreamEmpty( &p_sys->bytestream );
  862.         }
  863.         aout_DateSet( &p_sys->end_date, 0 );
  864.         block_Release( *pp_block );
  865.         return NULL;
  866.     }
  867.     if( !aout_DateGet( &p_sys->end_date ) && !(*pp_block)->i_pts )
  868.     {
  869.         /* We've just started the stream, wait for the first PTS. */
  870.         block_Release( *pp_block );
  871.         return NULL;
  872.     }
  873.     block_BytestreamPush( &p_sys->bytestream, *pp_block );
  874.     for( ;; )
  875.     {
  876.         switch( p_sys->i_state )
  877.         {
  878.         case STATE_NOSYNC:
  879.             while( block_PeekBytes( &p_sys->bytestream, p_header, 2 )
  880.                    == VLC_SUCCESS )
  881.             {
  882.                 /* Look for sync word - should be 0xfff(adts) or 0x2b7(loas) */
  883.                 if( p_header[0] == 0xff && (p_header[1] & 0xf6) == 0xf0 )
  884.                 {
  885.                     if( p_sys->i_type != TYPE_ADTS )
  886.                         msg_Dbg( p_dec, "detected ADTS format" );
  887.                     p_sys->i_state = STATE_SYNC;
  888.                     p_sys->i_type = TYPE_ADTS;
  889.                     break;
  890.                 }
  891.                 else if( p_header[0] == 0x56 && (p_header[1] & 0xe0) == 0xe0 )
  892.                 {
  893.                     if( p_sys->i_type != TYPE_LOAS )
  894.                         msg_Dbg( p_dec, "detected LOAS format" );
  895.                     p_sys->i_state = STATE_SYNC;
  896.                     p_sys->i_type = TYPE_LOAS;
  897.                     break;
  898.                 }
  899.                 block_SkipByte( &p_sys->bytestream );
  900.             }
  901.             if( p_sys->i_state != STATE_SYNC )
  902.             {
  903.                 block_BytestreamFlush( &p_sys->bytestream );
  904.                 /* Need more data */
  905.                 return NULL;
  906.             }
  907.         case STATE_SYNC:
  908.             /* New frame, set the Presentation Time Stamp */
  909.             p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
  910.             if( p_sys->i_pts != 0 &&
  911.                 p_sys->i_pts != aout_DateGet( &p_sys->end_date ) )
  912.             {
  913.                 aout_DateSet( &p_sys->end_date, p_sys->i_pts );
  914.             }
  915.             p_sys->i_state = STATE_HEADER;
  916.             break;
  917.         case STATE_HEADER:
  918.             if( p_sys->i_type == TYPE_ADTS )
  919.             {
  920.                 /* Get ADTS frame header (ADTS_HEADER_SIZE bytes) */
  921.                 if( block_PeekBytes( &p_sys->bytestream, p_header,
  922.                                      ADTS_HEADER_SIZE ) != VLC_SUCCESS )
  923.                 {
  924.                     /* Need more data */
  925.                     return NULL;
  926.                 }
  927.                 /* Check if frame is valid and get frame info */
  928.                 p_sys->i_frame_size = ADTSSyncInfo( p_dec, p_header,
  929.                                                     &p_sys->i_channels,
  930.                                                     &p_sys->i_rate,
  931.                                                     &p_sys->i_frame_length,
  932.                                                     &p_sys->i_header_size );
  933.             }
  934.             else
  935.             {
  936.                 assert( p_sys->i_type == TYPE_LOAS );
  937.                 /* Get LOAS frame header (LOAS_HEADER_SIZE bytes) */
  938.                 if( block_PeekBytes( &p_sys->bytestream, p_header,
  939.                                      LOAS_HEADER_SIZE ) != VLC_SUCCESS )
  940.                 {
  941.                     /* Need more data */
  942.                     return NULL;
  943.                 }
  944.                 /* Check if frame is valid and get frame info */
  945.                 p_sys->i_frame_size = LOASSyncInfo( p_header, &p_sys->i_header_size );
  946.             }
  947.             if( p_sys->i_frame_size <= 0 )
  948.             {
  949.                 msg_Dbg( p_dec, "emulated sync word" );
  950.                 block_SkipByte( &p_sys->bytestream );
  951.                 p_sys->i_state = STATE_NOSYNC;
  952.                 break;
  953.             }
  954.             p_sys->i_state = STATE_NEXT_SYNC;
  955.         case STATE_NEXT_SYNC:
  956.             /* TODO: If p_block == NULL, flush the buffer without checking the
  957.              * next sync word */
  958.             if( p_sys->bytestream.p_block == NULL )
  959.             {
  960.                 p_sys->i_state = STATE_NOSYNC;
  961.                 block_BytestreamFlush( &p_sys->bytestream );
  962.                 return NULL;
  963.             }
  964.             /* Check if next expected frame contains the sync word */
  965.             if( block_PeekOffsetBytes( &p_sys->bytestream, p_sys->i_frame_size
  966.                                        + p_sys->i_header_size, p_header, 2 )
  967.                 != VLC_SUCCESS )
  968.             {
  969.                 /* Need more data */
  970.                 return NULL;
  971.             }
  972.             assert( (p_sys->i_type == TYPE_ADTS) || (p_sys->i_type == TYPE_LOAS) );
  973.             if( ( ( p_sys->i_type == TYPE_ADTS ) &&
  974.                   ( p_header[0] != 0xff || (p_header[1] & 0xf6) != 0xf0 ) ) ||
  975.                 ( ( p_sys->i_type == TYPE_LOAS ) &&
  976.                   ( p_header[0] != 0x56 || (p_header[1] & 0xe0) != 0xe0 ) ) )
  977.             {
  978.                 msg_Dbg( p_dec, "emulated sync word "
  979.                          "(no sync on following frame)" );
  980.                 p_sys->i_state = STATE_NOSYNC;
  981.                 block_SkipByte( &p_sys->bytestream );
  982.                 break;
  983.             }
  984.             p_sys->i_state = STATE_SEND_DATA;
  985.             break;
  986.         case STATE_GET_DATA:
  987.             /* Make sure we have enough data.
  988.              * (Not useful if we went through NEXT_SYNC) */
  989.             if( block_WaitBytes( &p_sys->bytestream, p_sys->i_frame_size +
  990.                                  p_sys->i_header_size) != VLC_SUCCESS )
  991.             {
  992.                 /* Need more data */
  993.                 return NULL;
  994.             }
  995.             p_sys->i_state = STATE_SEND_DATA;
  996.         case STATE_SEND_DATA:
  997.             /* When we reach this point we already know we have enough
  998.              * data available. */
  999.             p_out_buffer = block_New( p_dec, p_sys->i_frame_size );
  1000.             if( !p_out_buffer )
  1001.             {
  1002.                 //p_dec->b_error = true;
  1003.                 return NULL;
  1004.             }
  1005.             p_buf = p_out_buffer->p_buffer;
  1006.             /* Skip the ADTS/LOAS header */
  1007.             block_SkipBytes( &p_sys->bytestream, p_sys->i_header_size );
  1008.             if( p_sys->i_type == TYPE_ADTS )
  1009.             {
  1010.                 /* Copy the whole frame into the buffer */
  1011.                 block_GetBytes( &p_sys->bytestream, p_buf, p_sys->i_frame_size );
  1012.             }
  1013.             else
  1014.             {
  1015.                 assert( p_sys->i_type == TYPE_LOAS );
  1016.                 /* Copy the whole frame into the buffer and parse/extract it */
  1017.                 block_GetBytes( &p_sys->bytestream, p_buf, p_sys->i_frame_size );
  1018.                 p_out_buffer->i_buffer = LOASParse( p_dec, p_buf, p_sys->i_frame_size );
  1019.                 if( p_out_buffer->i_buffer <= 0 )
  1020.                 {
  1021.                     if( !p_sys->b_latm_cfg )
  1022.                         msg_Warn( p_dec, "waiting for header" );
  1023.                     block_Release( p_out_buffer );
  1024.                     p_out_buffer = NULL;
  1025.                     p_sys->i_state = STATE_NOSYNC;
  1026.                     break;
  1027.                 }
  1028.             }
  1029.             SetupOutput( p_dec, p_out_buffer );
  1030.             /* Make sure we don't reuse the same pts twice */
  1031.             if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
  1032.                 p_sys->i_pts = p_sys->bytestream.p_block->i_pts = 0;
  1033.             /* So p_block doesn't get re-added several times */
  1034.             *pp_block = block_BytestreamPop( &p_sys->bytestream );
  1035.             p_sys->i_state = STATE_NOSYNC;
  1036.             return p_out_buffer;
  1037.         }
  1038.     }
  1039.     return NULL;
  1040. }
  1041. /*****************************************************************************
  1042.  * SetupBuffer:
  1043.  *****************************************************************************/
  1044. static void SetupOutput( decoder_t *p_dec, block_t *p_block )
  1045. {
  1046.     decoder_sys_t *p_sys = p_dec->p_sys;
  1047.     if( p_dec->fmt_out.audio.i_rate != p_sys->i_rate )
  1048.     {
  1049.         msg_Info( p_dec, "AAC channels: %d samplerate: %d",
  1050.                   p_sys->i_channels, p_sys->i_rate );
  1051.         aout_DateInit( &p_sys->end_date, p_sys->i_rate );
  1052.         aout_DateSet( &p_sys->end_date, p_sys->i_pts );
  1053.     }
  1054.     p_dec->fmt_out.audio.i_rate     = p_sys->i_rate;
  1055.     p_dec->fmt_out.audio.i_channels = p_sys->i_channels;
  1056.     p_dec->fmt_out.audio.i_bytes_per_frame = p_sys->i_frame_size;
  1057.     p_dec->fmt_out.audio.i_frame_length = p_sys->i_frame_length;
  1058. #if 0
  1059.     p_dec->fmt_out.audio.i_original_channels = p_sys->i_channels_conf;
  1060.     p_dec->fmt_out.audio.i_physical_channels =
  1061.         p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK;
  1062. #endif
  1063.     p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
  1064.     p_block->i_length =
  1065.         aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length ) - p_block->i_pts;
  1066. }
  1067. /*****************************************************************************
  1068.  * ClosePacketizer: clean up the packetizer
  1069.  *****************************************************************************/
  1070. static void ClosePacketizer( vlc_object_t *p_this )
  1071. {
  1072.     decoder_t *p_dec = (decoder_t *)p_this;
  1073.     decoder_sys_t *p_sys = p_dec->p_sys;
  1074.     block_BytestreamRelease( &p_sys->bytestream );
  1075.     free( p_dec->p_sys );
  1076. }