Mercurial > libavformat.hg
comparison mpegts.c @ 463:696f41bc8784 libavformat
store index for seeking in the native timebase of each stream
set correct timebase for nut
merge mpeg-ts seeking with existing seeking code
10l fix in mpegts (27mhz vs. 90khz)
author | michael |
---|---|
date | Sun, 23 May 2004 16:26:12 +0000 |
parents | b69898ffc92a |
children | 2846bb67dd8f |
comparison
equal
deleted
inserted
replaced
462:b69898ffc92a | 463:696f41bc8784 |
---|---|
766 } | 766 } |
767 break; | 767 break; |
768 } | 768 } |
769 st = av_new_stream(pes->stream, pes->pid); | 769 st = av_new_stream(pes->stream, pes->pid); |
770 if (st) { | 770 if (st) { |
771 av_set_pts_info(st, 60, 1, 27000000); | 771 av_set_pts_info(st, 60, 1, 90000); |
772 st->priv_data = pes; | 772 st->priv_data = pes; |
773 st->codec.codec_type = codec_type; | 773 st->codec.codec_type = codec_type; |
774 st->codec.codec_id = codec_id; | 774 st->codec.codec_id = codec_id; |
775 st->need_parsing = 1; | 775 st->need_parsing = 1; |
776 pes->st = st; | 776 pes->st = st; |
1282 if (ts->pids[i]) mpegts_close_filter(ts, ts->pids[i]); | 1282 if (ts->pids[i]) mpegts_close_filter(ts, ts->pids[i]); |
1283 return 0; | 1283 return 0; |
1284 } | 1284 } |
1285 | 1285 |
1286 static int64_t mpegts_get_pcr(AVFormatContext *s, int stream_index, | 1286 static int64_t mpegts_get_pcr(AVFormatContext *s, int stream_index, |
1287 int64_t *ppos, int find_next) | 1287 int64_t *ppos, int64_t pos_limit) |
1288 { | 1288 { |
1289 MpegTSContext *ts = s->priv_data; | 1289 MpegTSContext *ts = s->priv_data; |
1290 int64_t pos, timestamp; | 1290 int64_t pos, timestamp; |
1291 uint8_t buf[TS_PACKET_SIZE]; | 1291 uint8_t buf[TS_PACKET_SIZE]; |
1292 int pcr_l, pid; | 1292 int pcr_l, pid; |
1293 | 1293 const int find_next= 1; |
1294 pos = *ppos; | 1294 pos = ((*ppos + ts->raw_packet_size - 1) / ts->raw_packet_size) * ts->raw_packet_size; |
1295 if (find_next) { | 1295 if (find_next) { |
1296 for(;;) { | 1296 for(;;) { |
1297 url_fseek(&s->pb, pos, SEEK_SET); | 1297 url_fseek(&s->pb, pos, SEEK_SET); |
1298 if (get_buffer(&s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE) | 1298 if (get_buffer(&s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE) |
1299 return AV_NOPTS_VALUE; | 1299 return AV_NOPTS_VALUE; |
1318 break; | 1318 break; |
1319 } | 1319 } |
1320 } | 1320 } |
1321 } | 1321 } |
1322 *ppos = pos; | 1322 *ppos = pos; |
1323 | |
1323 return timestamp; | 1324 return timestamp; |
1324 } | |
1325 | |
1326 typedef int64_t ReadTimestampFunc(AVFormatContext *s, int stream_index, | |
1327 int64_t *ppos, int find_next); | |
1328 | |
1329 static int64_t do_block_align(int64_t val, int block_align) | |
1330 { | |
1331 return (val / block_align) * block_align; | |
1332 } | |
1333 | |
1334 /* XXX: use it in other formats */ | |
1335 static int timestamp_read_seek(AVFormatContext *s, | |
1336 int stream_index, int64_t timestamp, | |
1337 ReadTimestampFunc *read_timestamp, | |
1338 int block_align) | |
1339 { | |
1340 int64_t pos_min, pos_max, pos; | |
1341 int64_t dts_min, dts_max, dts; | |
1342 | |
1343 #ifdef DEBUG_SEEK | |
1344 printf("read_seek: %d %0.3f\n", stream_index, timestamp / 90000.0); | |
1345 #endif | |
1346 | |
1347 pos_min = 0; | |
1348 dts_min = read_timestamp(s, stream_index, &pos_min, 1); | |
1349 if (dts_min == AV_NOPTS_VALUE) { | |
1350 /* we can reach this case only if no PTS are present in | |
1351 the whole stream */ | |
1352 return -1; | |
1353 } | |
1354 pos_max = do_block_align(url_filesize(url_fileno(&s->pb)), block_align) - | |
1355 block_align; | |
1356 dts_max = read_timestamp(s, stream_index, &pos_max, 0); | |
1357 | |
1358 while (pos_min <= pos_max) { | |
1359 #ifdef DEBUG_SEEK | |
1360 printf("pos_min=0x%llx pos_max=0x%llx dts_min=%0.3f dts_max=%0.3f\n", | |
1361 pos_min, pos_max, | |
1362 dts_min / 90000.0, dts_max / 90000.0); | |
1363 #endif | |
1364 if (timestamp <= dts_min) { | |
1365 pos = pos_min; | |
1366 goto found; | |
1367 } else if (timestamp >= dts_max) { | |
1368 pos = pos_max; | |
1369 goto found; | |
1370 } else { | |
1371 /* interpolate position (better than dichotomy) */ | |
1372 pos = (int64_t)((double)(pos_max - pos_min) * | |
1373 (double)(timestamp - dts_min) / | |
1374 (double)(dts_max - dts_min)) + pos_min; | |
1375 pos = do_block_align(pos, block_align); | |
1376 } | |
1377 #ifdef DEBUG_SEEK | |
1378 printf("pos=0x%llx\n", pos); | |
1379 #endif | |
1380 /* read the next timestamp */ | |
1381 dts = read_timestamp(s, stream_index, &pos, 1); | |
1382 /* check if we are lucky */ | |
1383 if (dts == AV_NOPTS_VALUE) { | |
1384 /* should never happen */ | |
1385 pos = pos_min; | |
1386 goto found; | |
1387 } else if (timestamp == dts) { | |
1388 goto found; | |
1389 } else if (timestamp < dts) { | |
1390 pos_max = pos; | |
1391 dts_max = read_timestamp(s, stream_index, &pos_max, 0); | |
1392 if (dts_max == AV_NOPTS_VALUE) { | |
1393 /* should never happen */ | |
1394 break; | |
1395 } else if (timestamp >= dts_max) { | |
1396 pos = pos_max; | |
1397 goto found; | |
1398 } | |
1399 } else { | |
1400 pos_min = pos + block_align; | |
1401 dts_min = read_timestamp(s, stream_index, &pos_min, 1); | |
1402 if (dts_min == AV_NOPTS_VALUE) { | |
1403 /* should never happen */ | |
1404 goto found; | |
1405 } else if (timestamp <= dts_min) { | |
1406 goto found; | |
1407 } | |
1408 } | |
1409 } | |
1410 pos = pos_min; | |
1411 found: | |
1412 #ifdef DEBUG_SEEK | |
1413 pos_min = pos; | |
1414 dts_min = read_timestamp(s, stream_index, &pos_min, 1); | |
1415 pos_min += block_align; | |
1416 dts_max = read_timestamp(s, stream_index, &pos_min, 1); | |
1417 printf("pos=0x%llx %0.3f<=%0.3f<=%0.3f\n", | |
1418 pos, dts_min / 90000.0, timestamp / 90000.0, dts_max / 90000.0); | |
1419 #endif | |
1420 /* do the seek */ | |
1421 url_fseek(&s->pb, pos, SEEK_SET); | |
1422 return 0; | |
1423 } | |
1424 | |
1425 static int mpegts_read_seek(AVFormatContext *s, | |
1426 int stream_index, int64_t timestamp) | |
1427 { | |
1428 MpegTSContext *ts = s->priv_data; | |
1429 | |
1430 timestamp = (timestamp * 90000) / AV_TIME_BASE; | |
1431 | |
1432 return timestamp_read_seek(s, stream_index, timestamp, | |
1433 mpegts_get_pcr, ts->raw_packet_size); | |
1434 } | 1325 } |
1435 | 1326 |
1436 /**************************************************************/ | 1327 /**************************************************************/ |
1437 /* parsing functions - called from other demuxers such as RTP */ | 1328 /* parsing functions - called from other demuxers such as RTP */ |
1438 | 1329 |
1492 sizeof(MpegTSContext), | 1383 sizeof(MpegTSContext), |
1493 mpegts_probe, | 1384 mpegts_probe, |
1494 mpegts_read_header, | 1385 mpegts_read_header, |
1495 mpegts_read_packet, | 1386 mpegts_read_packet, |
1496 mpegts_read_close, | 1387 mpegts_read_close, |
1497 mpegts_read_seek, | 1388 NULL, //mpegts_read_seek, |
1389 mpegts_get_pcr, | |
1498 .flags = AVFMT_SHOW_IDS, | 1390 .flags = AVFMT_SHOW_IDS, |
1499 }; | 1391 }; |
1500 | 1392 |
1501 int mpegts_init(void) | 1393 int mpegts_init(void) |
1502 { | 1394 { |