[FFmpeg-devel] [PATCH] mpegts: limit teletext timestamps to [pcr; pcr + 40.6ms] range.

Reimar Döffinger Reimar.Doeffinger at gmx.de
Mon Sep 24 20:51:28 CEST 2012


The specification says they should not be buffered longer than
that, and this is also necessary since e.g. ORF HD sends teletext
with PES timestamps that are vastly off.

Signed-off-by: Reimar Döffinger <Reimar.Doeffinger at gmx.de>
---
 libavformat/mpegts.c |   18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index c39cf45..b8fa332 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -676,6 +676,16 @@ static void new_pes_packet(PESContext *pes, AVPacket *pkt)
         pkt->stream_index = pes->st->index;
     pkt->pts = pes->pts;
     pkt->dts = pes->dts;
+    if (pes->st->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT) {
+        // teletext packets do not always have correct timestamps,
+        // the standard says they should be handled after 40.6 ms at most.
+        int64_t pcr = pes->ts->cur_pcr / 300;
+        if (pkt->dts == AV_NOPTS_VALUE || pkt->dts < pcr) {
+            pkt->pts = pkt->dts = pcr;
+        } else if (pes->dts > pcr + 3654) {
+            pkt->pts = pkt->dts = pcr + 4654;
+        }
+    }
     /* store position of first TS packet of this PES packet */
     pkt->pos = pes->ts_packet_pos;
     pkt->flags = pes->flags;
@@ -1668,6 +1678,9 @@ static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
     }
 }
 
+static int parse_pcr(int64_t *ppcr_high, int *ppcr_low,
+                     const uint8_t *packet);
+
 /* handle one TS packet */
 static int handle_packet(MpegTSContext *ts, const uint8_t *packet)
 {
@@ -1677,6 +1690,8 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet)
         has_adaptation, has_payload;
     const uint8_t *p, *p_end;
     int64_t pos;
+    int64_t pcr_h;
+    int pcr_l;
 
     pid = AV_RB16(packet + 1) & 0x1fff;
     if(pid && discard_pid(ts, pid))
@@ -1733,6 +1748,9 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet)
     pos = avio_tell(ts->stream->pb);
     ts->pos47= pos % ts->raw_packet_size;
 
+    if (parse_pcr(&pcr_h, &pcr_l, packet) == 0)
+        ts->cur_pcr = pcr_h * 300 + pcr_l;
+
     if (tss->type == MPEGTS_SECTION) {
         if (is_start) {
             /* pointer field present */
-- 
1.7.10.4



More information about the ffmpeg-devel mailing list