| From fdd8caea6535434a877587f5325e914ba50ed17f Mon Sep 17 00:00:00 2001 |
| From: Cory Fields <theuni-nospam-@xbmc.org> |
| Date: Fri, 9 Jul 2010 16:43:31 -0400 |
| Subject: [PATCH 07/13] Read PID timestamps as well as PCR timestamps to find |
| location in mpegts stream |
| |
| Patch part of the XBMC patch set for ffmpeg, downloaded from |
| https://github.com/xbmc/FFmpeg/. |
| |
| Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de> |
| Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> |
| --- |
| libavformat/mpegts.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- |
| 1 file changed, 46 insertions(+), 2 deletions(-) |
| |
| diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c |
| index 25007a6..d5a8a45 100644 |
| --- a/libavformat/mpegts.c |
| +++ b/libavformat/mpegts.c |
| @@ -2459,6 +2459,44 @@ static void seek_back(AVFormatContext *s, AVIOContext *pb, int64_t pos) { |
| av_log(s, pb->seekable ? AV_LOG_ERROR : AV_LOG_INFO, "Unable to seek back to the start\n"); |
| } |
| |
| +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) |
| { |
| MpegTSContext *ts = s->priv_data; |
| @@ -2658,6 +2696,7 @@ static av_unused int64_t mpegts_get_pcr(AVFormatContext *s, int stream_index, |
| 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; |
| int pos47 = ts->pos47_full % ts->raw_packet_size; |
| pos = |
| ((*ppos + ts->raw_packet_size - 1 - pos47) / ts->raw_packet_size) * |
| @@ -2679,6 +2718,11 @@ static av_unused 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; |
| } |
| |
| @@ -2778,7 +2822,7 @@ AVInputFormat ff_mpegts_demuxer = { |
| .read_header = mpegts_read_header, |
| .read_packet = mpegts_read_packet, |
| .read_close = mpegts_read_close, |
| - .read_timestamp = mpegts_get_dts, |
| + .read_timestamp = mpegts_get_pcr, |
| .flags = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT, |
| .priv_class = &mpegts_class, |
| }; |
| @@ -2790,7 +2834,7 @@ AVInputFormat ff_mpegtsraw_demuxer = { |
| .read_header = mpegts_read_header, |
| .read_packet = mpegts_raw_read_packet, |
| .read_close = mpegts_read_close, |
| - .read_timestamp = mpegts_get_dts, |
| + .read_timestamp = mpegts_get_pcr, |
| .flags = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT, |
| .priv_class = &mpegtsraw_class, |
| }; |
| -- |
| 2.1.0 |
| |