MCPcopy Create free account
hub / github.com/FFMS/ffms2 / SeekTo

Method SeekTo

src/core/videosource.cpp:803–848  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

801}
802
803bool FFMS_VideoSource::SeekTo(int n, int SeekOffset) {
804 bool ForceSeek = false;
805 if (Stage == DecodeStage::INITIALIZE_SOURCE) {
806 ForceSeek = true;
807 Stage = DecodeStage::INITIALIZE;
808 }
809
810 // The semantics here are basically "return true if we don't know exactly where our seek ended up (destination isn't frame 0)"
811 if (SeekMode >= 0) {
812 int TargetFrame = n + SeekOffset;
813 if (TargetFrame < 0)
814 throw FFMS_Exception(FFMS_ERROR_SEEKING, FFMS_ERROR_UNKNOWN,
815 "Frame accurate seeking is not possible in this file");
816
817 // Seeking too close to the end of the stream can result in a different decoder delay since
818 // frames are returned as soon as draining starts, so avoid this to keep the delay predictable.
819 // Is the +1 necessary here? Not sure, but let's keep it to be safe.
820 int EndOfStreamDist = CodecContext->has_b_frames + 1;
821
822 if (CodecContext->codec_id == AV_CODEC_ID_H264)
823 // Work around a bug in ffmpeg's h264 decoder where frames are skipped when seeking too
824 // close to the end in open-gop files: https://trac.ffmpeg.org/ticket/10936
825 EndOfStreamDist *= 2;
826
827 TargetFrame = std::min(TargetFrame, Frames.RealFrameNumber(std::max(0, VP.NumFrames - 1 - EndOfStreamDist)));
828
829 if (SeekMode < 3)
830 TargetFrame = Frames.FindClosestVideoKeyFrame(TargetFrame);
831
832 if (SeekMode == 0) {
833 if (n < CurrentFrame) {
834 Seek(Frames[0].OriginalPos);
835 }
836 } else {
837 // 10 frames is used as a margin to prevent excessive seeking since the predicted best keyframe isn't always selected by avformat
838 if (ForceSeek || n < CurrentFrame || TargetFrame > CurrentFrame + 10 || (SeekMode == 3 && n > CurrentFrame + 10)) {
839 Seek(TargetFrame);
840 return true;
841 }
842 }
843 } else if (n < CurrentFrame) {
844 throw FFMS_Exception(FFMS_ERROR_SEEKING, FFMS_ERROR_INVALID_ARGUMENT,
845 "Non-linear access attempted");
846 }
847 return false;
848}
849
850FFMS_Frame *FFMS_VideoSource::GetFrame(int n) {
851 GetFrameCheck(n);

Callers

nothing calls this directly

Calls 3

FFMS_ExceptionClass · 0.85
RealFrameNumberMethod · 0.80

Tested by

no test coverage detected