diff --git a/src/core/track.cpp b/src/core/track.cpp index 604e1493df..0acf022f9d 100644 --- a/src/core/track.cpp +++ b/src/core/track.cpp @@ -177,12 +177,12 @@ int FFMS_Track::FrameFromPos(int64_t Pos, bool AllowHidden) const { return -1; } -int FFMS_Track::ClosestFrameFromPTS(int64_t PTS) const { +int FFMS_Track::ClosestFrameFromPTS(int64_t PTS, bool AllowHidden) const { FrameInfo F; F.PTS = PTS; auto Pos = std::lower_bound(begin(), end(), F, PTSComparison); - while (Pos != end() && Pos->Skipped() && Pos->PTS == PTS) + while (Pos != end() && (!AllowHidden && Pos->Skipped()) && Pos->PTS == PTS) Pos++; if (Pos == end()) diff --git a/src/core/track.h b/src/core/track.h index dde1321881..ad6960681e 100644 --- a/src/core/track.h +++ b/src/core/track.h @@ -82,9 +82,9 @@ struct FFMS_Track { void FillAudioGaps(); int FindClosestVideoKeyFrame(int Frame) const; - int FrameFromPTS(int64_t PTS, bool AllowHidden = false) const; - int FrameFromPos(int64_t Pos, bool AllowHidden = false) const; - int ClosestFrameFromPTS(int64_t PTS) const; + int FrameFromPTS(int64_t PTS, bool AllowHidden = true) const; + int FrameFromPos(int64_t Pos, bool AllowHidden = true) const; + int ClosestFrameFromPTS(int64_t PTS, bool AllowHidden = true) const; int RealFrameNumber(int Frame) const; int VisibleFrameCount() const; diff --git a/src/core/videosource.cpp b/src/core/videosource.cpp index c27b5d6f98..cc579ba78e 100644 --- a/src/core/videosource.cpp +++ b/src/core/videosource.cpp @@ -498,7 +498,7 @@ FFMS_VideoSource::~FFMS_VideoSource() { FFMS_Frame *FFMS_VideoSource::GetFrameByTime(double Time) { // The final 1/1000th of a PTS is added to avoid frame duplication due to floating point math inexactness // Basically only a problem when the fps is externally set to the same or a multiple of the input clip fps - int Frame = Frames.ClosestFrameFromPTS(static_cast(((Time * 1000 * Frames.TB.Den) / Frames.TB.Num) + .001)); + int Frame = Frames.ClosestFrameFromPTS(static_cast(((Time * 1000 * Frames.TB.Den) / Frames.TB.Num) + .001), false); return GetFrame(Frame); } @@ -743,7 +743,7 @@ bool FFMS_VideoSource::DecodePacket(AVPacket *Packet) { std::swap(DecodeFrame, LastDecodedFrame); ResendPacket = false; - int PacketNum = Frames.FrameFromPTS(Frames.UseDTS ? Packet->dts : Packet->pts, true); + int PacketNum = Frames.FrameFromPTS(Frames.UseDTS ? Packet->dts : Packet->pts); bool PacketHidden = !!(Packet->flags & AV_PKT_FLAG_DISCARD) || (PacketNum != -1 && Frames[PacketNum].MarkedHidden); bool SecondField = PacketNum != -1 && Frames[PacketNum].SecondField; @@ -918,11 +918,6 @@ bool FFMS_VideoSource::SeekTo(int n, int SeekOffset) { // Is the +1 necessary here? Not sure, but let's keep it to be safe. int EndOfStreamDist = CodecContext->has_b_frames + 1; - if (CodecContext->codec_id == AV_CODEC_ID_H264) - // Work around a bug in ffmpeg's h264 decoder where frames are skipped when seeking too - // close to the end in open-gop files: https://trac.ffmpeg.org/ticket/10936 - EndOfStreamDist *= 2; - TargetFrame = std::min(TargetFrame, Frames.RealFrameNumber(std::max(0, VP.NumFrames - 1 - EndOfStreamDist))); if (SeekMode < 3)