summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTaylor Ralph <tralph@mythtv.org>2011-02-21 03:18:49 (GMT)
committer Taylor Ralph <tralph@mythtv.org>2011-02-21 03:18:49 (GMT)
commit8ba07a0ae3b31a2f3f87f6822b5efdaa8ff1bd9c (patch)
tree8a65865be7d648302947fced20aeb4a9355a07e2
parent4ce4707321aeec4387af11804265d9d4dba7b388 (diff)
Improve timestamp logging and restrict fixup code.
The new logging is greatly improved to provide information such as which timestamps are active (reordered or dts) and if fixups are being invoked. We now only provide fixups for timestamps that are equal to or upto one frame interval less than the last video timestamp. The previous code would fixup timestamps that were upto 10 seconds behind the last used video timestamp. This caused the code to start tracking a bogus timestamp upto 10 seconds in the future. I'm seriously considering just removing fixups for timestamps in the past. We now use reordered pts timestamps and if they have issues then we switch back to using dts. This should mean that we really only need fixups for missing timestamps which are normal for some types of video. It would be interesting to know if there are any videos out there without any good type of timestamps available and if so what we could realistically do about it. Backport from 9af38c8b3d7091c4bd84 since it provides a much easier way to debug timestamp issues until the next release.
-rw-r--r--mythtv/libs/libmythtv/avformatdecoder.cpp24
-rw-r--r--mythtv/libs/libmythtv/avformatdecoder.h1
2 files changed, 18 insertions, 7 deletions
diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp
index e9f30d8..0e6c7ef 100644
--- a/mythtv/libs/libmythtv/avformatdecoder.cpp
+++ b/mythtv/libs/libmythtv/avformatdecoder.cpp
@@ -267,6 +267,7 @@ AvFormatDecoder::AvFormatDecoder(MythPlayer *parent,
last_dts_for_fault_detection(0),
pts_detected(false),
reordered_pts_detected(false),
+ pts_selected(true),
using_null_videoout(use_null_videoout),
video_codec_id(kCodec_NONE),
no_hardware_decoders(no_hardware_decode),
@@ -3116,29 +3117,34 @@ bool AvFormatDecoder::ProcessVideoPacket(AVStream *curstream, AVPacket *pkt)
{
if (pkt->dts != (int64_t)AV_NOPTS_VALUE)
pts = pkt->dts;
+ pts_selected = false;
}
else if (private_dec && private_dec->NeedsReorderedPTS() &&
mpa_pic.reordered_opaque != (int64_t)AV_NOPTS_VALUE)
{
pts = mpa_pic.reordered_opaque;
+ pts_selected = true;
}
else if (faulty_pts <= faulty_dts && reordered_pts_detected)
{
if (mpa_pic.reordered_opaque != (int64_t)AV_NOPTS_VALUE)
pts = mpa_pic.reordered_opaque;
+ pts_selected = true;
}
else if (pkt->dts != (int64_t)AV_NOPTS_VALUE)
{
pts = pkt->dts;
+ pts_selected = false;
}
- long long temppts = (long long)(av_q2d(curstream->time_base) * pts * 1000);
+ long long vpts = (long long)(av_q2d(curstream->time_base) * pts * 1000);
+ long long temppts = vpts;
// Validate the video pts against the last pts. If it's
// a little bit smaller, equal or missing, compute
// it from the last. Otherwise assume a wraparound.
if (!ringBuffer->isDVD() &&
temppts <= lastvpts &&
- (temppts + 10000 > lastvpts || temppts <= 0))
+ (temppts + (1000 / fps) > lastvpts || temppts <= 0))
{
temppts = lastvpts;
temppts += (long long)(1000 / fps);
@@ -3147,8 +3153,11 @@ bool AvFormatDecoder::ProcessVideoPacket(AVStream *curstream, AVPacket *pkt)
}
VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC +
- QString("video timecode %1 %2 %3 %4 %5").arg(mpa_pic.reordered_opaque)
- .arg(pkt->pts).arg(pkt->dts).arg(temppts).arg(lastvpts));
+ QString("video timecode %1 %2 %3 %4 %5 %6 (%7 active)%8")
+ .arg(mpa_pic.reordered_opaque).arg(pkt->pts).arg(pkt->dts)
+ .arg(vpts).arg(temppts).arg(lastvpts)
+ .arg((pts_selected) ? "reordered" : "dts")
+ .arg((vpts != temppts) ? " fixup" : ""));
/* XXX: Broken.
if (mpa_pic.qscale_table != NULL && mpa_pic.qstride > 0 &&
@@ -3264,7 +3273,7 @@ bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic)
// it from the last. Otherwise assume a wraparound.
if (!ringBuffer->isDVD() &&
temppts <= lastvpts &&
- (temppts + 10000 > lastvpts || temppts <= 0))
+ (temppts + (1000 / fps) > lastvpts || temppts <= 0))
{
temppts = lastvpts;
temppts += (long long)(1000 / fps);
@@ -3273,8 +3282,9 @@ bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic)
}
VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC +
- QString("ProcessVideoFrame timecode %1 %2 %3")
- .arg(mpa_pic->reordered_opaque).arg(temppts).arg(lastvpts));
+ QString("ProcessVideoFrame timecode %1 %2 %3%4")
+ .arg(mpa_pic->reordered_opaque).arg(pts).arg(temppts).arg(lastvpts)
+ .arg((pts != temppts) ? " fixup" : ""));
picframe->interlaced_frame = mpa_pic->interlaced_frame;
picframe->top_field_first = mpa_pic->top_field_first;
diff --git a/mythtv/libs/libmythtv/avformatdecoder.h b/mythtv/libs/libmythtv/avformatdecoder.h
index 0f10bb2..8d3a300 100644
--- a/mythtv/libs/libmythtv/avformatdecoder.h
+++ b/mythtv/libs/libmythtv/avformatdecoder.h
@@ -286,6 +286,7 @@ class AvFormatDecoder : public DecoderBase
int64_t last_dts_for_fault_detection;
bool pts_detected;
bool reordered_pts_detected;
+ bool pts_selected;
bool using_null_videoout;
MythCodecID video_codec_id;