Mercurial > libavformat.hg
comparison utils.c @ 1496:7e288adde245 libavformat
split av_seek_frame_binary() so the code becomes idependant of AVInputFormat and AVIndex
author | michael |
---|---|
date | Tue, 14 Nov 2006 01:34:36 +0000 |
parents | 5e1b279a26d2 |
children | 1eaba8bc0ab1 |
comparison
equal
deleted
inserted
replaced
1495:04909cf98da7 | 1496:7e288adde245 |
---|---|
1161 */ | 1161 */ |
1162 int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts, int flags){ | 1162 int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts, int flags){ |
1163 AVInputFormat *avif= s->iformat; | 1163 AVInputFormat *avif= s->iformat; |
1164 int64_t pos_min, pos_max, pos, pos_limit; | 1164 int64_t pos_min, pos_max, pos, pos_limit; |
1165 int64_t ts_min, ts_max, ts; | 1165 int64_t ts_min, ts_max, ts; |
1166 int64_t start_pos, filesize; | 1166 int index; |
1167 int index, no_change; | |
1168 AVStream *st; | 1167 AVStream *st; |
1169 | 1168 |
1170 if (stream_index < 0) | 1169 if (stream_index < 0) |
1171 return -1; | 1170 return -1; |
1172 | 1171 |
1210 pos_max,pos_limit, ts_max); | 1209 pos_max,pos_limit, ts_max); |
1211 #endif | 1210 #endif |
1212 } | 1211 } |
1213 } | 1212 } |
1214 | 1213 |
1214 pos= av_gen_search(s, stream_index, target_ts, pos_min, pos_max, pos_limit, ts_min, ts_max, flags, &ts, avif->read_timestamp); | |
1215 if(pos<0) | |
1216 return -1; | |
1217 | |
1218 /* do the seek */ | |
1219 url_fseek(&s->pb, pos, SEEK_SET); | |
1220 | |
1221 av_update_cur_dts(s, st, ts); | |
1222 | |
1223 return 0; | |
1224 } | |
1225 | |
1226 /** | |
1227 * Does a binary search using read_timestamp(). | |
1228 * this isnt supposed to be called directly by a user application, but by demuxers | |
1229 * @param target_ts target timestamp in the time base of the given stream | |
1230 * @param stream_index stream number | |
1231 */ | |
1232 int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, int64_t pos_min, int64_t pos_max, int64_t pos_limit, int64_t ts_min, int64_t ts_max, int flags, int64_t *ts_ret, int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t )){ | |
1233 int64_t pos, ts; | |
1234 int64_t start_pos, filesize; | |
1235 int no_change; | |
1236 | |
1237 #ifdef DEBUG_SEEK | |
1238 av_log(s, AV_LOG_DEBUG, "gen_seek: %d %"PRId64"\n", stream_index, target_ts); | |
1239 #endif | |
1240 | |
1215 if(ts_min == AV_NOPTS_VALUE){ | 1241 if(ts_min == AV_NOPTS_VALUE){ |
1216 pos_min = s->data_offset; | 1242 pos_min = s->data_offset; |
1217 ts_min = avif->read_timestamp(s, stream_index, &pos_min, INT64_MAX); | 1243 ts_min = read_timestamp(s, stream_index, &pos_min, INT64_MAX); |
1218 if (ts_min == AV_NOPTS_VALUE) | 1244 if (ts_min == AV_NOPTS_VALUE) |
1219 return -1; | 1245 return -1; |
1220 } | 1246 } |
1221 | 1247 |
1222 if(ts_max == AV_NOPTS_VALUE){ | 1248 if(ts_max == AV_NOPTS_VALUE){ |
1223 int step= 1024; | 1249 int step= 1024; |
1224 filesize = url_fsize(&s->pb); | 1250 filesize = url_fsize(&s->pb); |
1225 pos_max = filesize - 1; | 1251 pos_max = filesize - 1; |
1226 do{ | 1252 do{ |
1227 pos_max -= step; | 1253 pos_max -= step; |
1228 ts_max = avif->read_timestamp(s, stream_index, &pos_max, pos_max + step); | 1254 ts_max = read_timestamp(s, stream_index, &pos_max, pos_max + step); |
1229 step += step; | 1255 step += step; |
1230 }while(ts_max == AV_NOPTS_VALUE && pos_max >= step); | 1256 }while(ts_max == AV_NOPTS_VALUE && pos_max >= step); |
1231 if (ts_max == AV_NOPTS_VALUE) | 1257 if (ts_max == AV_NOPTS_VALUE) |
1232 return -1; | 1258 return -1; |
1233 | 1259 |
1234 for(;;){ | 1260 for(;;){ |
1235 int64_t tmp_pos= pos_max + 1; | 1261 int64_t tmp_pos= pos_max + 1; |
1236 int64_t tmp_ts= avif->read_timestamp(s, stream_index, &tmp_pos, INT64_MAX); | 1262 int64_t tmp_ts= read_timestamp(s, stream_index, &tmp_pos, INT64_MAX); |
1237 if(tmp_ts == AV_NOPTS_VALUE) | 1263 if(tmp_ts == AV_NOPTS_VALUE) |
1238 break; | 1264 break; |
1239 ts_max= tmp_ts; | 1265 ts_max= tmp_ts; |
1240 pos_max= tmp_pos; | 1266 pos_max= tmp_pos; |
1241 if(tmp_pos >= filesize) | 1267 if(tmp_pos >= filesize) |
1275 pos= pos_min + 1; | 1301 pos= pos_min + 1; |
1276 else if(pos > pos_limit) | 1302 else if(pos > pos_limit) |
1277 pos= pos_limit; | 1303 pos= pos_limit; |
1278 start_pos= pos; | 1304 start_pos= pos; |
1279 | 1305 |
1280 ts = avif->read_timestamp(s, stream_index, &pos, INT64_MAX); //may pass pos_limit instead of -1 | 1306 ts = read_timestamp(s, stream_index, &pos, INT64_MAX); //may pass pos_limit instead of -1 |
1281 if(pos == pos_max) | 1307 if(pos == pos_max) |
1282 no_change++; | 1308 no_change++; |
1283 else | 1309 else |
1284 no_change=0; | 1310 no_change=0; |
1285 #ifdef DEBUG_SEEK | 1311 #ifdef DEBUG_SEEK |
1299 | 1325 |
1300 pos = (flags & AVSEEK_FLAG_BACKWARD) ? pos_min : pos_max; | 1326 pos = (flags & AVSEEK_FLAG_BACKWARD) ? pos_min : pos_max; |
1301 ts = (flags & AVSEEK_FLAG_BACKWARD) ? ts_min : ts_max; | 1327 ts = (flags & AVSEEK_FLAG_BACKWARD) ? ts_min : ts_max; |
1302 #ifdef DEBUG_SEEK | 1328 #ifdef DEBUG_SEEK |
1303 pos_min = pos; | 1329 pos_min = pos; |
1304 ts_min = avif->read_timestamp(s, stream_index, &pos_min, INT64_MAX); | 1330 ts_min = read_timestamp(s, stream_index, &pos_min, INT64_MAX); |
1305 pos_min++; | 1331 pos_min++; |
1306 ts_max = avif->read_timestamp(s, stream_index, &pos_min, INT64_MAX); | 1332 ts_max = read_timestamp(s, stream_index, &pos_min, INT64_MAX); |
1307 av_log(s, AV_LOG_DEBUG, "pos=0x%"PRIx64" %"PRId64"<=%"PRId64"<=%"PRId64"\n", | 1333 av_log(s, AV_LOG_DEBUG, "pos=0x%"PRIx64" %"PRId64"<=%"PRId64"<=%"PRId64"\n", |
1308 pos, ts_min, target_ts, ts_max); | 1334 pos, ts_min, target_ts, ts_max); |
1309 #endif | 1335 #endif |
1310 /* do the seek */ | 1336 *ts_ret= ts; |
1311 url_fseek(&s->pb, pos, SEEK_SET); | 1337 return pos; |
1312 | |
1313 av_update_cur_dts(s, st, ts); | |
1314 | |
1315 return 0; | |
1316 } | 1338 } |
1317 | 1339 |
1318 static int av_seek_frame_byte(AVFormatContext *s, int stream_index, int64_t pos, int flags){ | 1340 static int av_seek_frame_byte(AVFormatContext *s, int stream_index, int64_t pos, int flags){ |
1319 int64_t pos_min, pos_max; | 1341 int64_t pos_min, pos_max; |
1320 #if 0 | 1342 #if 0 |