Mercurial > libavformat.hg
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 = { |