Permalink
Browse files

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.
  • Loading branch information...
1 parent eb573d2 commit 9af38c8b3d7091c4bd84e1dfc01dcc68bae227a3 @tralph tralph committed Feb 20, 2011
Showing with 17 additions and 8 deletions.
  1. +16 −8 mythtv/libs/libmythtv/avformatdecoder.cpp
  2. +1 −0 mythtv/libs/libmythtv/avformatdecoder.h
@@ -242,6 +242,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),
@@ -2830,25 +2831,30 @@ 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;
}
-
+
VERBOSE(VB_PLAYBACK+VB_TIMESTAMP+VB_EXTRA, LOC +
- QString("video packet timestamps reordered %1 pts %2 dts %3")
- .arg(mpa_pic.reordered_opaque).arg(pkt->pts).arg(pkt->dts));
+ QString("video packet timestamps reordered %1 pts %2 dts %3 (%4 active)")
+ .arg(mpa_pic.reordered_opaque).arg(pkt->pts).arg(pkt->dts)
+ .arg((pts_selected) ? "reordered" : "dts"));
mpa_pic.reordered_opaque = pts;
@@ -2919,15 +2925,16 @@ bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic)
return false;
}
- long long temppts = (long long)(av_q2d(stream->time_base) *
- mpa_pic->reordered_opaque * 1000);
+ long long pts = (long long)(av_q2d(stream->time_base) *
+ mpa_pic->reordered_opaque * 1000);
+ long long temppts = pts;
// 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);
@@ -2936,8 +2943,9 @@ bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic)
}
VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC +
- QString("video timecode %1 %2 %3")
- .arg(mpa_pic->reordered_opaque).arg(temppts).arg(lastvpts));
+ QString("video timecode %1 %2 %3 %4%5")
+ .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;
@@ -290,6 +290,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;

0 comments on commit 9af38c8

Please sign in to comment.