Changeset 367


Ignore:
Timestamp:
12/13/07 19:24:42 (15 years ago)
Author:
radscorpion
Message:

added a few methods to parse seek table offset and seek table. Golomb codes are not working yet... I'll do it at home.

Location:
dsfilters/demux_mpc/src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • dsfilters/demux_mpc/src/bits.cpp

    r366 r367  
    113113}
    114114
     115int32 Bitstream::Get_Golomb(int k)
     116{
     117        int32 len = 0;
     118        NeedBits24();
     119        while (UGetBits(1) == 1) len++;
     120        if (len == 0) return 0;
     121        NeedBits24();
     122
     123        //while (bits
     124
     125        int32 val = (1 << len) | UGetBits(len);
     126    return val;
     127}
     128
  • dsfilters/demux_mpc/src/bits.h

    r366 r367  
    8686        int32 Get_ME(int32 mode);
    8787        int32 Get_TE(int32 range);
     88        int32 Get_Golomb(int k);
    8889
    8990        inline int32 Size_UE(uint32 val)
  • dsfilters/demux_mpc/src/mpc_file.cpp

    r366 r367  
    1919        duration_10mhz(0),
    2020        reader(NULL),
    21         packet(NULL)
     21        packet(NULL),
     22        seek_table(NULL),
     23        seek_table_position(0)
    2224{
    2325        key = 0;
     
    3133CMPCFile::~CMPCFile()
    3234{
     35        if (seek_table) {
     36                free(seek_table);
     37                seek_table = NULL;
     38        }
    3339        if (packet) {
    3440                free(packet);
     
    4248        HRESULT         hr;
    4349        int                     ret;
     50        bool            done;
    4451
    4552        // keep a local copy of the reader
     
    4754
    4855
    49         /*
    50                 According to stream specification the first 4 bytes should be 'MPCK'
    51         */
     56        // According to stream specification the first 4 bytes should be 'MPCK'
    5257        uint32  magick;
    5358        reader->Seek(0);
     
    5863        }
    5964
     65        // means no seek table
     66        seek_table_position = 0;
     67        seek_table_size = 0;
     68
     69        done = false;
     70
    6071        // now loop through a few packets
    6172        do {
    62                 int ret = ReadNextPacket();
     73                ret = ReadNextPacket();
    6374                if (ret < 0) return -1;                 // end of file reached before initialization is done ?
    6475
     
    6677                case MPC_KEY('S','H'):  ret = ReadStreamHeader(); break;
    6778                case MPC_KEY('R','G'):  ret = ReadReplaygain(); break;
    68 
    69                 // TODO: Seek Table
     79                case MPC_KEY('S','O'):  ret = ReadSeekOffset(); break;
    7080
    7181                // audio packet - initialization is over
    72                 case MPC_KEY('A','P'):  return 0;
     82                case MPC_KEY('A','P'):  done = true; break;
    7383                }
    7484
    7585                // if parsing failed we quit
    7686                if (ret < 0) return ret;
    77         } while (1);
     87        } while (!done);
     88
     89        // if there was a seek table, load it
     90        if (seek_table_position != 0) {
     91                ret = ReadSeekTable();
     92                if (ret < 0) return ret;
     93        }
    7894
    7995        return 0;
     
    86102        int32   size_len;
    87103        int             ret;
    88 
     104        int64   avail;
     105
     106        reader->GetPosition(&packet_pos, &avail);
    89107        ret = reader->GetKey(key_val);                                  if (ret < 0) return ret;
    90108        ret = reader->GetSizeElm(size_val, size_len);   if (ret < 0) return ret;
     
    96114        // size_val is the total size including key, variable size field and payload
    97115        packet_size = size_val - 2 - size_len;
    98 
    99         // !!!!
    100116        ASSERT(packet_size <= packet_max_size);
    101117
     
    123139}
    124140
     141int CMPCFile::ReadSeekOffset()
     142{
     143        Bitstream       b(packet);
     144
     145        seek_table_position = b.GetMpcSize();
     146        seek_table_position += packet_pos;
     147
     148        // success
     149        return 0;
     150}
     151
     152int CMPCFile::ReadSeekTable()
     153{
     154        reader->Seek(seek_table_position);
     155        int ret;
     156
     157        ret = ReadNextPacket();
     158        if (ret < 0) return ret;
     159
     160        Bitstream       b(packet);
     161
     162        // calculate size as seen in mpc_demux.c
     163        int64 tmp = b.GetMpcSize();     b.NeedBits();
     164        seek_table_size = tmp;
     165        int     seek_pwr = block_pwr + b.UGetBits(4);
     166        tmp = 2+total_samples / (1152 << seek_pwr);
     167        if (tmp < seek_table_size) tmp = seek_table_size;
     168
     169        // alloc memory for seek table
     170        seek_table = (uint32*)malloc(tmp * sizeof(uint32));
     171
     172        uint32 *table = seek_table;
     173
     174        tmp = b.GetMpcSize();
     175        table[0] = (uint32)(tmp + header_position) * 8;
     176        if (seek_table_size == 1) return 0;
     177
     178        tmp = b.GetMpcSize();
     179        table[1] = (uint32)(tmp + header_position) * 8;
     180        for (int i=2; i<seek_table_size; i++) {
     181                int code = b.Get_Golomb(12);
     182                if (code&1) code = -(code&(-1 << 1));
     183                code <<= 2;
     184                table[i] = code + 2*table[i-1] - table[i-2];
     185        }
     186
     187        return 0;
     188}
     189
    125190int CMPCFile::ReadStreamHeader()
    126191{
     
    157222                        //      Stream Version 8
    158223                        //-----------------------------------------------------------------
    159                         int64   samples = b.GetMpcSize();
     224                        total_samples = b.GetMpcSize();
    160225                        int64   silence = b.GetMpcSize();
    161226
     
    173238
    174239                        // let's calculate duration
    175                         duration_10mhz = (samples * 10000000) / sample_rate;
     240                        duration_10mhz = (total_samples * 10000000) / sample_rate;
    176241
    177242                        b.DumpBits(5);                                  // bands
     
    180245                        b.NeedBits();
    181246                        b.DumpBits(1);                                  // mid side
    182                         int exp = b.UGetBits(3);
    183                         audio_block_frames = 1 << (2*exp);
     247                        block_pwr = b.UGetBits(3) * 2;
     248                        audio_block_frames = 1 << (block_pwr);
     249
     250                        // store absolute position of stream header
     251                        header_position = packet_pos;
    184252                }
    185253                break;
  • dsfilters/demux_mpc/src/mpc_file.h

    r366 r367  
    2727        int                             channels;
    2828        int                             audio_block_frames;
     29        int                             block_pwr;                             
     30        int                             seek_pwr;
     31        int64                   total_samples;
    2932
    3033        // replay gain
     
    3336        float                   gain_album_db;
    3437        float                   gain_album_peak_db;
     38
     39        // seeking table
     40        int64                   seek_table_position;            // position of seeking table in file
     41        int64                   header_position;
     42        uint32                  *seek_table;
     43        int64                   seek_table_size;
    3544
    3645        // internals
     
    4251        int                             packet_max_size;                // maximum allowed packet size
    4352        int                             packet_size;                    // size of currently loaded payload
     53        int64                   packet_pos;                             // absolute position in file
    4454       
    4555public:
     
    5464        int ReadStreamHeader();
    5565        int ReadReplaygain();
     66        int ReadSeekOffset();
     67        int ReadSeekTable();
    5668
    5769};
Note: See TracChangeset for help on using the changeset viewer.