[FFmpeg-cvslog] mpegts: add and use mpegts_get_dts()
Joakim Plate
elupus at ecce.se
Sat Oct 22 13:31:33 CEST 2011
Michael Niedermayer <git <at> videolan.org> writes:
>
> ffmpeg | branch: master | Michael Niedermayer <michaelni <at> gmx.at> | Fri
Oct 21 16:11:00 2011 +0200|
> [de9862a95e0e0a81a3e787e449faa32247feef71] | committer: Michael Niedermayer
>
> mpegts: add and use mpegts_get_dts()
>
We did something like this quite a while ago in xbmc to avoid modifying state on
a failed seek. Ie no flush by calling read_timestamp functions. It may be worth
using in your new read_dts function.
(inlined and won't apply anymore):
>From 708be9614b55ccac65bf269bbf74909727004cf6 Mon Sep 17 00:00:00 2001
From: Cory Fields <theuni-nospam- at xbmc.org>
Date: Fri, 9 Jul 2010 16:43:31 -0400
Subject: [PATCH] Read PID timestamps as well as PCR timestamps to find
location in mpegts stream
---
libavformat/mpegts.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 46 insertions(+), 2 deletions(-)
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 1acc1a3..b38f6bc 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -1549,6 +1549,44 @@ static int parse_pcr(int64_t *ppcr_high, int *ppcr_low,
return 0;
}
+static int parse_timestamp(int64_t *ts, const uint8_t *buf)
+{
+ int afc, flags;
+ const uint8_t *p;
+
+ if(!(buf[1] & 0x40)) /* must be a start packet */
+ return -1;
+
+ afc = (buf[3] >> 4) & 3;
+ p = buf + 4;
+ if (afc == 0 || afc == 2) /* invalid or only adaption field */
+ return -1;
+ if (afc == 3)
+ p += p[0] + 1;
+ if (p >= buf + TS_PACKET_SIZE)
+ return -1;
+
+ if (p[0] != 0x00 || p[1] != 0x00 || p[2] != 0x01) /*
packet_start_code_prefix */
+ return -1;
+
+ flags = p[3] | 0x100; /* stream type */
+ if (!((flags >= 0x1c0 && flags <= 0x1df) ||
+ (flags >= 0x1e0 && flags <= 0x1ef) ||
+ (flags == 0x1bd) || (flags == 0x1fd)))
+ return -1;
+
+ flags = p[7];
+ if ((flags & 0xc0) == 0x80) {
+ *ts = ff_parse_pes_pts(p+9);
+ return 0;
+ } else if ((flags & 0xc0) == 0xc0) {
+ *ts = ff_parse_pes_pts(p+9+5);
+ return 0;
+ }
+ return -1;
+}
+
+
static int mpegts_read_header(AVFormatContext *s,
AVFormatParameters *ap)
{
@@ -1736,6 +1774,7 @@ static int64_t mpegts_get_pcr(AVFormatContext *s, int
stream_index,
int64_t pos, timestamp;
uint8_t buf[TS_PACKET_SIZE];
int pcr_l, pcr_pid = ((PESContext*)s->streams[stream_index]->priv_data)-
>pcr_pid;
+ int pid = ((PESContext*)s->streams[stream_index]->priv_data)->pid;
pos = ((*ppos + ts->raw_packet_size - 1 - ts->pos47) / ts-
>raw_packet_size) * ts->raw_packet_size + ts->pos47;
while(pos < pos_limit) {
if (avio_seek(s->pb, pos, SEEK_SET) < 0)
@@ -1753,6 +1792,11 @@ static int64_t mpegts_get_pcr(AVFormatContext *s, int
stream_index,
*ppos = pos;
return timestamp;
}
+ if ((pid < 0 || (AV_RB16(buf + 1) & 0x1fff) == pid) &&
+ parse_timestamp(×tamp, buf) == 0) {
+ *ppos = pos;
+ return timestamp;
+ }
pos += ts->raw_packet_size;
}
@@ -1934,7 +1978,7 @@ AVInputFormat ff_mpegts_demuxer = {
.read_header = mpegts_read_header,
.read_packet = mpegts_read_packet,
.read_close = mpegts_read_close,
- .read_seek = read_seek,
+ .read_seek = NULL,
.read_timestamp = mpegts_get_pcr,
.flags = AVFMT_SHOW_IDS|AVFMT_TS_DISCONT,
#ifdef USE_SYNCPOINT_SEARCH
@@ -1949,7 +1993,7 @@ AVInputFormat ff_mpegtsraw_demuxer = {
.read_header = mpegts_read_header,
.read_packet = mpegts_raw_read_packet,
.read_close = mpegts_read_close,
- .read_seek = read_seek,
+ .read_seek = NULL,
.read_timestamp = mpegts_get_pcr,
.flags = AVFMT_SHOW_IDS|AVFMT_TS_DISCONT,
#ifdef USE_SYNCPOINT_SEARCH
--
1.7.5.4
More information about the ffmpeg-cvslog
mailing list