static int stream_seek_frame(mpg123_handle *fr, off_t newframe) { debug2("seek_frame to %"OFF_P" (from %"OFF_P")", (off_p)newframe, (off_p)fr->num); /* Seekable streams can go backwards and jump forwards. Non-seekable streams still can go forward, just not jump. */ if((fr->rdat.flags & READER_SEEKABLE) || (newframe >= fr->num)) { off_t preframe; /* a leading frame we jump to */ off_t seek_to; /* the byte offset we want to reach */ off_t to_skip; /* bytes to skip to get there (can be negative) */ /* now seek to nearest leading index position and read from there until newframe is reached. We use skip_bytes, which handles seekable and non-seekable streams (the latter only for positive offset, which we ensured before entering here). */ seek_to = frame_index_find(fr, newframe, &preframe); /* No need to seek to index position if we are closer already. But I am picky about fr->num == newframe, play safe by reading the frame again. If you think that's stupid, don't call a seek to the current frame. */ if(fr->num >= newframe || fr->num < preframe) { to_skip = seek_to - fr->rd->tell(fr); if(fr->rd->skip_bytes(fr, to_skip) != seek_to) return READER_ERROR; debug2("going to %lu; just got %lu", (long unsigned)newframe, (long unsigned)preframe); fr->num = preframe-1; /* Watch out! I am going to read preframe... fr->num should indicate the frame before! */ } while(fr->num < newframe) { /* try to be non-fatal now... frameNum only gets advanced on success anyway */ if(!read_frame(fr)) break; } /* Now the wanted frame should be ready for decoding. */ debug1("arrived at %lu", (long unsigned)fr->num); return MPG123_OK; } else { fr->err = MPG123_NO_SEEK; return READER_ERROR; /* invalid, no seek happened */ } }
static int stream_seek_frame( mpg123_handle_t *fr, mpg_off_t newframe ) { // seekable streams can go backwards and jump forwards. // non-seekable streams still can go forward, just not jump. if(( fr->rdat.flags & READER_SEEKABLE ) || ( newframe >= fr->num )) { mpg_off_t preframe; // a leading frame we jump to mpg_off_t seek_to; // the byte offset we want to reach mpg_off_t to_skip; // bytes to skip to get there (can be negative) // now seek to nearest leading index position and read from there until newframe is reached. // we use skip_bytes, which handles seekable and non-seekable streams // (the latter only for positive offset, which we ensured before entering here). seek_to = frame_index_find( fr, newframe, &preframe ); // no need to seek to index position if we are closer already. // but I am picky about fr->num == newframe, play safe by reading the frame again. // if you think that's stupid, don't call a seek to the current frame. if( fr->num >= newframe || fr->num < preframe ) { to_skip = seek_to - fr->rd->tell( fr ); if( fr->rd->skip_bytes( fr, to_skip ) != seek_to ) return MPG123_ERR; fr->num = preframe - 1; // watch out! I am going to read preframe... fr->num should indicate the frame before! } while( fr->num < newframe ) { // try to be non-fatal now... frameNum only gets advanced on success anyway if( !read_frame( fr )) break; } // now the wanted frame should be ready for decoding. return MPG123_OK; } else { fr->err = MPG123_NO_SEEK; return MPG123_ERR; // invalid, no seek happened } }