diff options
Diffstat (limited to 'apps/codecs')
-rw-r--r-- | apps/codecs/libtremor/vorbisfile.c | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/apps/codecs/libtremor/vorbisfile.c b/apps/codecs/libtremor/vorbisfile.c index 9365ba344b..f0a83364ec 100644 --- a/apps/codecs/libtremor/vorbisfile.c +++ b/apps/codecs/libtremor/vorbisfile.c | |||
@@ -193,7 +193,7 @@ static void _add_serialno(ogg_page *og,ogg_uint32_t **serialno_list, int *n){ | |||
193 | } | 193 | } |
194 | 194 | ||
195 | /* returns nonzero if found */ | 195 | /* returns nonzero if found */ |
196 | static int _lookup_serialno(long s, ogg_uint32_t *serialno_list, int n){ | 196 | static int _lookup_serialno(ogg_uint32_t s, ogg_uint32_t *serialno_list, int n){ |
197 | if(serialno_list){ | 197 | if(serialno_list){ |
198 | while(n--){ | 198 | while(n--){ |
199 | if(*serialno_list == (ogg_uint32_t) s) return 1; | 199 | if(*serialno_list == (ogg_uint32_t) s) return 1; |
@@ -204,7 +204,7 @@ static int _lookup_serialno(long s, ogg_uint32_t *serialno_list, int n){ | |||
204 | } | 204 | } |
205 | 205 | ||
206 | static int _lookup_page_serialno(ogg_page *og, ogg_uint32_t *serialno_list, int n){ | 206 | static int _lookup_page_serialno(ogg_page *og, ogg_uint32_t *serialno_list, int n){ |
207 | long s = ogg_page_serialno(og); | 207 | ogg_uint32_t s = ogg_page_serialno(og); |
208 | return _lookup_serialno(s,serialno_list,n); | 208 | return _lookup_serialno(s,serialno_list,n); |
209 | } | 209 | } |
210 | 210 | ||
@@ -245,12 +245,12 @@ static ogg_int64_t _get_prev_page_serial(OggVorbis_File *vf, | |||
245 | ret_gran=ogg_page_granulepos(&og); | 245 | ret_gran=ogg_page_granulepos(&og); |
246 | offset=ret; | 246 | offset=ret; |
247 | 247 | ||
248 | if(ret_serialno == (ogg_uint32_t) *serialno){ | 248 | if((ogg_uint32_t)ret_serialno == (ogg_uint32_t)*serialno){ |
249 | prefoffset=ret; | 249 | prefoffset=ret; |
250 | *granpos=ret_gran; | 250 | *granpos=ret_gran; |
251 | } | 251 | } |
252 | 252 | ||
253 | if(!_lookup_serialno(ret_serialno,serial_list,serial_n)){ | 253 | if(!_lookup_serialno((ogg_uint32_t)ret_serialno,serial_list,serial_n)){ |
254 | /* we fell off the end of the link, which means we seeked | 254 | /* we fell off the end of the link, which means we seeked |
255 | back too far and shouldn't have been looking in that link | 255 | back too far and shouldn't have been looking in that link |
256 | to begin with. If we found the preferred serial number, | 256 | to begin with. If we found the preferred serial number, |
@@ -1201,6 +1201,36 @@ int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){ | |||
1201 | return OV_EBADLINK; | 1201 | return OV_EBADLINK; |
1202 | } | 1202 | } |
1203 | 1203 | ||
1204 | /* rescales the number x from the range of [0,from] to [0,to] | ||
1205 | x is in the range [0,from] | ||
1206 | from, to are in the range [1, 1<<62-1] */ | ||
1207 | ogg_int64_t rescale64(ogg_int64_t x, ogg_int64_t from, ogg_int64_t to){ | ||
1208 | ogg_int64_t frac=0; | ||
1209 | ogg_int64_t ret=0; | ||
1210 | int i; | ||
1211 | if(x >= from) return to; | ||
1212 | if(x <= 0) return 0; | ||
1213 | |||
1214 | for(i=0;i<64;i++){ | ||
1215 | if(x>=from){ | ||
1216 | frac|=1; | ||
1217 | x-=from; | ||
1218 | } | ||
1219 | x<<=1; | ||
1220 | frac<<=1; | ||
1221 | } | ||
1222 | |||
1223 | for(i=0;i<64;i++){ | ||
1224 | if(frac & 1){ | ||
1225 | ret+=to; | ||
1226 | } | ||
1227 | frac>>=1; | ||
1228 | ret>>=1; | ||
1229 | } | ||
1230 | |||
1231 | return ret; | ||
1232 | } | ||
1233 | |||
1204 | /* Page granularity seek (faster than sample granularity because we | 1234 | /* Page granularity seek (faster than sample granularity because we |
1205 | don't do the last bit of decode to find a specific sample). | 1235 | don't do the last bit of decode to find a specific sample). |
1206 | 1236 | ||
@@ -1246,8 +1276,9 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){ | |||
1246 | bisect=begin; | 1276 | bisect=begin; |
1247 | }else{ | 1277 | }else{ |
1248 | /* take a (pretty decent) guess. */ | 1278 | /* take a (pretty decent) guess. */ |
1249 | bisect=begin + | 1279 | bisect=begin + rescale64(target-begintime, |
1250 | (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE; | 1280 | endtime-begintime, |
1281 | end-begin) - CHUNKSIZE; | ||
1251 | if(bisect<begin+CHUNKSIZE) | 1282 | if(bisect<begin+CHUNKSIZE) |
1252 | bisect=begin; | 1283 | bisect=begin; |
1253 | } | 1284 | } |