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