Skip to content

Commit c9bb63a

Browse files
ahmadsharif1facebook-github-bot
authored andcommitted
[torchcodec] Return subsequent frame if FFMPEG seeks past end of the frame (#178)
Summary: Pull Request resolved: #178 The way get_frame_displayed_at works is as follows: We call avformat_seek_file with: `min_ts=-inf ts=timestamp max_ts=timestamp` https://ffmpeg.org/doxygen/7.0/group__lavf__decoding.html#ga3b40fc8d2fda6992ae6ea2567d71ba30 This should in theory never seek past our timestamp. However for some videos ffmpeg does seek past our timestamp. And that causes us to never return a valid frame in that case. The fix is to warn the user and return the first frame after the timestamp if this ever happens. Differential Revision: D61139386
1 parent dbfef12 commit c9bb63a

File tree

1 file changed

+20
-8
lines changed

1 file changed

+20
-8
lines changed

src/torchcodec/decoders/_core/VideoDecoder.cpp

+20-8
Original file line numberDiff line numberDiff line change
@@ -934,14 +934,26 @@ VideoDecoder::DecodedOutput VideoDecoder::getFrameDisplayedAtTimestampNoDemux(
934934
}
935935
}
936936
setCursorPtsInSeconds(seconds);
937-
return getDecodedOutputWithFilter(
938-
[seconds, this](int frameStreamIndex, AVFrame* frame) {
939-
StreamInfo& stream = streams_[frameStreamIndex];
940-
double frameStartTime = ptsToSeconds(frame->pts, stream.timeBase);
941-
double frameEndTime =
942-
ptsToSeconds(frame->pts + getDuration(frame), stream.timeBase);
943-
return seconds >= frameStartTime && seconds < frameEndTime;
944-
});
937+
return getDecodedOutputWithFilter([seconds, this](
938+
int frameStreamIndex, AVFrame* frame) {
939+
StreamInfo& stream = streams_[frameStreamIndex];
940+
double frameStartTime = ptsToSeconds(frame->pts, stream.timeBase);
941+
double frameEndTime =
942+
ptsToSeconds(frame->pts + getDuration(frame), stream.timeBase);
943+
if (frameStartTime > seconds) {
944+
// FFMPEG seeked past the frame we are looking for even though we
945+
// set max_ts to be our needed timestamp in avformat_seek_file()
946+
// in maybeSeekToBeforeDesiredPts().
947+
// In this case we return the very next frame instead of throwing an
948+
// exception.
949+
std::cerr
950+
<< "TorchCodec: WARNING: ffmpeg seeked past requested timestamp="
951+
<< seconds << ". Returning frame with startTime=" << frameStartTime
952+
<< " endTime=" << frameEndTime << std::endl;
953+
return true;
954+
}
955+
return seconds >= frameStartTime && seconds < frameEndTime;
956+
});
945957
}
946958

947959
void VideoDecoder::validateUserProvidedStreamIndex(uint64_t streamIndex) {

0 commit comments

Comments
 (0)