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 {