Ignore:
Timestamp:
11/17/06 21:04:35 (15 years ago)
Author:
r2d
Message:
  • added simple seeking for sv7 and sv8
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libmpc/branches/r2d/libmpcdec/mpc_demux.c

    r139 r143  
    5353
    5454enum {
    55         MPC_BUFFER_CLEAR = 1,
    56         MPC_BUFFER_SWAP = 2,
    57         MPC_BUFFER_FULL = 4,
     55        MPC_BUFFER_SWAP = 1,
     56        MPC_BUFFER_FULL = 2,
    5857};
     58
     59static void mpc_demux_clear_buff(mpc_demux * d)
     60{
     61        d->bytes_total = 0;
     62        d->bits_reader.buff = d->buffer;
     63        d->bits_reader.count = 8;
     64        d->block_bits = 0;
     65        d->end = MPC_FALSE;
     66}
    5967
    6068static mpc_uint32_t
     
    95103
    96104        return 0;
     105}
     106
     107/**
     108 * seek to a bit position in the stream
     109 * @param d
     110 * @param fpos position in the stream in bits from the beginning of mpc datas
     111 * @param min_bytes number of bytes to load after seeking
     112 */
     113static void
     114mpc_demux_seek(mpc_demux * d, mpc_uint32_t fpos, mpc_uint32_t min_bytes) {
     115//      mpc_uint32_t cur_pos = d->r->tell(d->r);
     116        mpc_uint32_t next_pos;
     117        mpc_int_t bit_offset;
     118
     119        // FIXME : do not flush the buffer if fpos is in the current buffer
     120
     121        next_pos = fpos >> 3;
     122        if (d->si.stream_version == 7)
     123                next_pos &= (-1u << 2);
     124        bit_offset = fpos - (next_pos << 3);
     125        next_pos += d->si.header_position; // add id3 offset
     126
     127        d->r->seek(d->r, next_pos);
     128        mpc_demux_clear_buff(d);
     129        if (d->si.stream_version == 7)
     130                mpc_demux_fill(d, (min_bytes + ((bit_offset + 7) >> 3) + 3) & (-1 << 2), MPC_BUFFER_SWAP);
     131        else
     132                mpc_demux_fill(d, min_bytes + ((bit_offset + 7) >> 3), 0);
     133        d->bits_reader.buff += bit_offset >> 3;
     134        d->bits_reader.count = 8 - (bit_offset & 7);
    97135}
    98136
     
    159197        if (p_tmp != 0) {
    160198                p_tmp->r = p_reader;
    161                 p_tmp->bytes_total = 0;
    162                 p_tmp->bits_reader.buff = p_tmp->buffer;
    163                 p_tmp->bits_reader.count = 8;
    164                 p_tmp->block_bits = 0;
    165                 p_tmp->end = MPC_FALSE;
     199                mpc_demux_clear_buff(p_tmp);
    166200                // lire entête
    167201                if (mpc_demux_header(p_tmp) == MPC_STATUS_OK) {
     
    190224void mpc_demux_decode(mpc_demux * d, mpc_frame_info * i)
    191225{
    192         if (d->si.stream_version == 8) {
     226        if (d->si.stream_version >= 8) {
    193227                mpc_bits_reader r;
    194                 if (d->block_bits < 8 && d->end == MPC_FALSE){
     228                if (d->block_bits < 8 && d->end == MPC_FALSE) {
    195229                        mpc_block b;
    196230                        d->bits_reader.count &= -8;
    197231                        mpc_demux_fill(d, 11, 0); // max header block size
    198232                        mpc_bits_get_block(&d->bits_reader, &b);
    199                         while( memcmp(b.key, "AD", 2) != 0 ){ // scan all blocks until audio
    200                                 if (memcmp(b.key, "SE", 2) == 0) // end block
     233                        while( memcmp(b.key, "AD", 2) != 0 ) { // scan all blocks until audio
     234                                if (memcmp(b.key, "SE", 2) == 0) { // end block
    201235                                        d->end = MPC_TRUE;
     236                                        break;
     237                                }
    202238                                mpc_demux_fill(d, 11 + b.size, 0);
    203239                                d->bits_reader.buff += b.size;
     
    206242                        d->block_bits = b.size * 8;
    207243                }
    208 
     244                // FIXME : this is not good if block size > buffer size
    209245                mpc_demux_fill(d, (d->block_bits >> 3) + 1, 0);
    210246                r = d->bits_reader;
     
    220256}
    221257
     258mpc_status mpc_demux_seek_second(mpc_demux * d, double seconds)
     259{
     260        return mpc_demux_seek_sample(d, (mpc_int64_t)(seconds * (double)d->si.sample_freq + 0.5));
     261}
     262
     263mpc_status mpc_demux_seek_sample(mpc_demux * d, mpc_int64_t destsample)
     264{
     265        mpc_uint32_t fwd, samples_to_skip, fpos = 32, i;
     266
     267        if (destsample > d->si.samples) destsample = d->si.samples;
     268        fwd = (mpc_uint32_t) (destsample / (MPC_FRAME_LENGTH * d->si.frames_per_block));
     269        samples_to_skip = MPC_DECODER_SYNTH_DELAY + (mpc_uint32_t)
     270                        (destsample % (MPC_FRAME_LENGTH * d->si.frames_per_block));
     271
     272        // FIXME : we start seeking from the beginning of the file, easier but not optimal
     273        d->d->decoded_samples = 0;
     274
     275        if (d->si.stream_version >= 8) {
     276                mpc_block b;
     277                int size;
     278                mpc_demux_seek(d, fpos, 11);
     279                size = mpc_bits_get_block(&d->bits_reader, &b);
     280                for( i = 0; i < fwd; ){
     281                        if (memcmp(b.key, "AD", 2) == 0){
     282                                i++;
     283                                d->d->decoded_samples += MPC_FRAME_LENGTH * d->si.frames_per_block;
     284                        }
     285                        fpos += (b.size + size) * 8;
     286                        mpc_demux_seek(d, fpos, 11);
     287                        size = mpc_bits_get_block(&d->bits_reader, &b);
     288                }
     289                d->bits_reader.buff -= size;
     290        } else {
     291                if (fwd > 32) {
     292                        fwd -= 32;
     293                        samples_to_skip += MPC_FRAME_LENGTH * 32;
     294                } else {
     295                        samples_to_skip += MPC_FRAME_LENGTH * fwd;
     296                        fwd = 0;
     297                }
     298                mpc_decoder_reset_scf(d->d);
     299                fpos += 21 * 8;
     300                mpc_demux_seek(d, fpos, 4);
     301                for( i = 0; i < fwd; i++){
     302                        fpos += mpc_bits_read(&d->bits_reader, 20) + 20;
     303                        mpc_demux_seek(d, fpos, 4);
     304                        d->d->decoded_samples += MPC_FRAME_LENGTH;
     305                }
     306        }
     307        d->d->samples_to_skip = samples_to_skip;
     308        return MPC_STATUS_OK;
     309}
Note: See TracChangeset for help on using the changeset viewer.