summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarton Balint <cus@passwd.hu>2013-08-04 04:17:22 +0200
committerMichael Niedermayer <michaelni@gmx.at>2013-08-06 02:47:38 +0200
commita7bb12a307568c0db72e6eb8d496a5651a8228df (patch)
treee1dcf0cbd20c2bae71f9a87c4099300c127bec26
parent4c15f3491f1991554ad497788dfb6ad02b552134 (diff)
mpegts: add fix_teletext_pts mpegts demuxer option
Changes since v1 of the patch: - enable option by default - add documentation - move up PTS override code after PES header parsing, to ensure we use the last PCR before the first packet of the teletext PES packet. The option overrides teletext packet PTS and DTS values with the timestamps calculated from the PCR of the first program which the teletext stream is part of and 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. The patch does not do PCR interpolation to estimate the PCR of the teltetext packet, it just uses the last PCR of the program, which may cause a slight error (0.1 sec) in the teletext packet pts-es. 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@passwd.hu> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--doc/demuxers.texi13
-rw-r--r--libavformat/mpegts.c47
-rw-r--r--libavformat/version.h2
3 files changed, 59 insertions, 3 deletions
diff --git a/doc/demuxers.texi b/doc/demuxers.texi
index 1a4d739268..e18448f779 100644
--- a/doc/demuxers.texi
+++ b/doc/demuxers.texi
@@ -257,6 +257,19 @@ ffmpeg -pattern_type glob -i "*.png" -r 10 out.mkv
@end example
@end itemize
+@section mpegts
+
+MPEG-2 transport stream demuxer.
+
+@table @option
+
+@item fix_teletext_pts
+Overrides teletext packet PTS and DTS values with the timestamps calculated
+from the PCR of the first program which the teletext stream is part of and is
+not discarded. Default value is 1, set this option to 0 if you want your
+teletext packet PTS and DTS values untouched.
+@end table
+
@section rawvideo
Raw video demuxer.
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index c7c957f635..beaed3180b 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 = 1}, 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,
};
@@ -968,6 +984,32 @@ static int mpegts_push_data(MpegTSFilter *filter,
p += sl_header_bytes;
buf_size -= sl_header_bytes;
}
+ 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.
+ // TODO: we should interpolate the PCR, not just use the last one
+ 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 (pes->dts == AV_NOPTS_VALUE || pes->dts < pcr) {
+ pes->pts = pes->dts = pcr;
+ } else if (pes->dts > pcr + 3654 + 9000) {
+ pes->pts = pes->dts = pcr + 3654 + 9000;
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
}
break;
case MPEGTS_PAYLOAD:
@@ -2325,6 +2367,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 bea7c7b67f..c2ca0ab935 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -31,7 +31,7 @@
#define LIBAVFORMAT_VERSION_MAJOR 55
#define LIBAVFORMAT_VERSION_MINOR 13
-#define LIBAVFORMAT_VERSION_MICRO 101
+#define LIBAVFORMAT_VERSION_MICRO 102
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
LIBAVFORMAT_VERSION_MINOR, \