[FFmpeg-devel] [PATCH 3/4] mpegts: add fix_teletext_pts mpegts demuxer option

Marton Balint cus at passwd.hu
Sat Jul 27 21:14:46 CEST 2013


The option (if set) overrides teletext packet pts with the PCR of a program
which the teletext stream is part of that is not discarded. Using the same
teletext PID for multiple programs is possible, therefore we need some kind of
heuristics to know which program PCR we should synchronize to. Using the first
non-discarded PCR pid among the programs of the teletext stream seemed like a
good choice.

Based on a patch by Reimar Döffinger.
http://lists.ffmpeg.org/pipermail/ffmpeg-devel/2012-September/131610.html

Signed-off-by: Marton Balint <cus at passwd.hu>
---
 libavformat/mpegts.c  | 46 ++++++++++++++++++++++++++++++++++++++++++++--
 libavformat/version.h |  2 +-
 2 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index c7c957f..5e2af02 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -106,6 +106,9 @@ struct MpegTSContext {
     /** compute exact PCR for each transport stream packet   */
     int mpeg2ts_compute_pcr;
 
+    /** fix dvb teletext pts                                 */
+    int fix_teletext_pts;
+
     int64_t cur_pcr;    /**< used to estimate the exact PCR  */
     int pcr_incr;       /**< used to estimate the exact PCR  */
 
@@ -131,7 +134,7 @@ struct MpegTSContext {
     int current_pid;
 };
 
-static const AVOption options[] = {
+static const AVOption mpegtsraw_options[] = {
     {"compute_pcr", "Compute exact PCR for each transport stream packet.", offsetof(MpegTSContext, mpeg2ts_compute_pcr), AV_OPT_TYPE_INT,
      {.i64 = 0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
     { NULL },
@@ -140,7 +143,20 @@ static const AVOption options[] = {
 static const AVClass mpegtsraw_class = {
     .class_name = "mpegtsraw demuxer",
     .item_name  = av_default_item_name,
-    .option     = options,
+    .option     = mpegtsraw_options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+static const AVOption mpegts_options[] = {
+    {"fix_teletext_pts", "Try to fix pts values of dvb teletext streams.", offsetof(MpegTSContext, fix_teletext_pts), AV_OPT_TYPE_INT,
+     {.i64 = 0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
+    { NULL },
+};
+
+static const AVClass mpegts_class = {
+    .class_name = "mpegts demuxer",
+    .item_name  = av_default_item_name,
+    .option     = mpegts_options,
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
@@ -721,6 +737,31 @@ 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->ts->fix_teletext_pts && pes->st->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT) {
+        AVProgram *p = NULL;
+        while ((p = av_find_program_from_stream(pes->stream, p, pes->st->index))) {
+            if (p->pcr_pid != -1 && p->discard != AVDISCARD_ALL) {
+                MpegTSFilter *f = pes->ts->pids[p->pcr_pid];
+                if (f && f->type == MPEGTS_PES) {
+                    PESContext *pcrpes = f->u.pes_filter.opaque;
+                    if (pcrpes && pcrpes->last_pcr != -1 && pcrpes->st && pcrpes->st->discard != AVDISCARD_ALL) {
+                        // teletext packets do not always have correct timestamps,
+                        // the standard says they should be handled after 40.6 ms at most,
+                        // and the pcr error to this packet should be no more than 100 ms.
+                        int64_t pcr = pcrpes->last_pcr / 300;
+                        pes->st->pts_wrap_reference = pcrpes->st->pts_wrap_reference;
+                        pes->st->pts_wrap_behavior = pcrpes->st->pts_wrap_behavior;
+                        if (pkt->dts == AV_NOPTS_VALUE || pkt->dts < pcr) {
+                            pkt->pts = pkt->dts = pcr;
+                        } else if (pes->dts > pcr + 3654 + 9000) {
+                            pkt->pts = pkt->dts = pcr + 3654 + 9000;
+                        }
+                        break;
+                    }
+                }
+            }
+        }
+    }
     /* store position of first TS packet of this PES packet */
     pkt->pos = pes->ts_packet_pos;
     pkt->flags = pes->flags;
@@ -2325,6 +2366,7 @@ AVInputFormat ff_mpegts_demuxer = {
     .read_close     = mpegts_read_close,
     .read_timestamp = mpegts_get_dts,
     .flags          = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT,
+    .priv_class     = &mpegts_class,
 };
 
 AVInputFormat ff_mpegtsraw_demuxer = {
diff --git a/libavformat/version.h b/libavformat/version.h
index ed1c196..abac051 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -31,7 +31,7 @@
 
 #define LIBAVFORMAT_VERSION_MAJOR 55
 #define LIBAVFORMAT_VERSION_MINOR 12
-#define LIBAVFORMAT_VERSION_MICRO 102
+#define LIBAVFORMAT_VERSION_MICRO 103
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
                                                LIBAVFORMAT_VERSION_MINOR, \
-- 
1.8.1.4



More information about the ffmpeg-devel mailing list