comparison asf.c @ 351:c072833fe7f4 libavformat

use packet number instead of byte number internally for seeking
author michael
date Wed, 14 Jan 2004 18:40:29 +0000
parents 9a6c7a56405c
children c5ea5cdb5b58
comparison
equal deleted inserted replaced
350:9a6c7a56405c 351:c072833fe7f4
1297 av_free(st->codec.palctrl); 1297 av_free(st->codec.palctrl);
1298 } 1298 }
1299 return 0; 1299 return 0;
1300 } 1300 }
1301 1301
1302 static int64_t asf_align(AVFormatContext *s, int64_t pos){
1303 ASFContext *asf = s->priv_data;
1304 assert(pos >= 0);
1305
1306 return pos/ asf->packet_size * asf->packet_size;
1307 }
1308
1309 // Added to support seeking after packets have been read 1302 // Added to support seeking after packets have been read
1310 // If information is not reset, read_packet fails due to 1303 // If information is not reset, read_packet fails due to
1311 // leftover information from previous reads 1304 // leftover information from previous reads
1312 static void asf_reset_header(AVFormatContext *s) 1305 static void asf_reset_header(AVFormatContext *s)
1313 { 1306 {
1352 AVPacket pkt1, *pkt = &pkt1; 1345 AVPacket pkt1, *pkt = &pkt1;
1353 ASFStream *asf_st; 1346 ASFStream *asf_st;
1354 int64_t pts; 1347 int64_t pts;
1355 int64_t pos= *ppos; 1348 int64_t pos= *ppos;
1356 1349
1357 // ensure we are on the packet boundry
1358 assert(pos % asf->packet_size == 0);
1359 //printf("asf_read_pts\n"); 1350 //printf("asf_read_pts\n");
1360 url_fseek(&s->pb, pos + s->data_offset, SEEK_SET); 1351 url_fseek(&s->pb, pos*asf->packet_size + s->data_offset, SEEK_SET);
1361 asf_reset_header(s); 1352 asf_reset_header(s);
1362 do{ 1353 do{
1363 if (av_read_frame(s, pkt) < 0){ 1354 if (av_read_frame(s, pkt) < 0){
1364 printf("seek failed\n"); 1355 printf("seek failed\n");
1365 return AV_NOPTS_VALUE; 1356 return AV_NOPTS_VALUE;
1367 pts= pkt->pts; 1358 pts= pkt->pts;
1368 1359
1369 av_free_packet(pkt); 1360 av_free_packet(pkt);
1370 }while(pkt->stream_index != stream_index || !(pkt->flags&PKT_FLAG_KEY)); 1361 }while(pkt->stream_index != stream_index || !(pkt->flags&PKT_FLAG_KEY));
1371 asf_st= s->streams[stream_index]->priv_data; 1362 asf_st= s->streams[stream_index]->priv_data;
1372 *ppos= asf_st->packet_pos - s->data_offset; 1363
1364 assert((asf_st->packet_pos - s->data_offset) % asf->packet_size == 0);
1365 *ppos= (asf_st->packet_pos - s->data_offset) / asf->packet_size;
1373 //printf("found keyframe at %Ld stream %d stamp:%Ld\n", *ppos, stream_index, pts); 1366 //printf("found keyframe at %Ld stream %d stamp:%Ld\n", *ppos, stream_index, pts);
1374 1367
1375 return pts; 1368 return pts;
1376 } 1369 }
1377 1370
1389 1382
1390 pos_min = 0; 1383 pos_min = 0;
1391 pts_min = asf_read_pts(s, &pos_min, stream_index); 1384 pts_min = asf_read_pts(s, &pos_min, stream_index);
1392 if (pts_min == AV_NOPTS_VALUE) return -1; 1385 if (pts_min == AV_NOPTS_VALUE) return -1;
1393 1386
1394 pos_max = asf_align(s, url_filesize(url_fileno(&s->pb)) - 1 - s->data_offset); //FIXME wrong 1387 pos_max = (url_filesize(url_fileno(&s->pb)) - 1 - s->data_offset) / asf->packet_size; //FIXME wrong
1395 pts_max = pts_min + s->duration; 1388 pts_max = pts_min + s->duration;
1396 pos_limit= pos_max; 1389 pos_limit= pos_max;
1397 1390
1398 while (pos_min < pos_limit) { 1391 while (pos_min < pos_limit) {
1399 int64_t start_pos; 1392 int64_t start_pos;
1400 1393
1401 assert(pos_limit <= pos_max); 1394 assert(pos_limit <= pos_max);
1402 assert(pos_limit % asf->packet_size == 0);
1403 assert(pos_max % asf->packet_size == 0);
1404 assert(pos_min % asf->packet_size == 0);
1405 1395
1406 // interpolate position (better than dichotomy) 1396 // interpolate position (better than dichotomy)
1407 pos = (int64_t)((double)(pos_limit - pos_min) * 1397 pos = (int64_t)((double)(pos_limit - pos_min) *
1408 (double)(pts - pts_min) / 1398 (double)(pts - pts_min) /
1409 (double)(pts_max - pts_min)) + pos_min; 1399 (double)(pts_max - pts_min)) + pos_min;
1410 pos= asf_align(s, pos); 1400 pos/= asf->packet_size;
1411 if(pos <= pos_min) 1401 if(pos <= pos_min)
1412 pos= pos_min + asf->packet_size; 1402 pos= pos_min + 1;
1413 else if(pos > pos_limit) 1403 else if(pos > pos_limit)
1414 pos= pos_limit; 1404 pos= pos_limit;
1415 start_pos= pos; 1405 start_pos= pos;
1416 1406
1417 // read the next timestamp 1407 // read the next timestamp
1418 cur_pts = asf_read_pts(s, &pos, stream_index); 1408 cur_pts = asf_read_pts(s, &pos, stream_index);
1419 1409
1420 if (cur_pts == AV_NOPTS_VALUE) { 1410 if (cur_pts == AV_NOPTS_VALUE) {
1421 return -1; 1411 return -1;
1422 } else if (pts < cur_pts) { 1412 } else if (pts < cur_pts) {
1423 pos_limit = start_pos - asf->packet_size; 1413 pos_limit = start_pos - 1;
1424 pos_max = pos; 1414 pos_max = pos;
1425 pts_max = cur_pts; 1415 pts_max = cur_pts;
1426 } else { 1416 } else {
1427 pos_min = pos; 1417 pos_min = pos;
1428 pts_min = cur_pts; 1418 pts_min = cur_pts;
1430 if (pts == cur_pts) 1420 if (pts == cur_pts)
1431 break; 1421 break;
1432 } 1422 }
1433 } 1423 }
1434 pos = pos_min; 1424 pos = pos_min;
1435 url_fseek(&s->pb, pos + s->data_offset, SEEK_SET); 1425 url_fseek(&s->pb, pos*asf->packet_size + s->data_offset, SEEK_SET);
1436 asf_reset_header(s); 1426 asf_reset_header(s);
1437 return 0; 1427 return 0;
1438 } 1428 }
1439 1429
1440 static AVInputFormat asf_iformat = { 1430 static AVInputFormat asf_iformat = {