Commit a7bb12a3 authored by Marton Balint's avatar Marton Balint Committed by Michael Niedermayer

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.htmlSigned-off-by: 's avatarMarton Balint <cus@passwd.hu>
Signed-off-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parent 4c15f349
......@@ -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.
......
......@@ -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 = {
......
......@@ -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, \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment