ffmpegdecoder: handle media that starts at a non-zero pts

This commit is contained in:
itsmattkc
2020-02-21 00:09:45 +11:00
parent 162c91ec52
commit 2299fda73a
2 changed files with 22 additions and 5 deletions
+21 -5
View File
@@ -45,6 +45,7 @@ FFmpegDecoder::FFmpegDecoder() :
fmt_ctx_(nullptr),
codec_ctx_(nullptr),
scale_ctx_(nullptr),
cache_at_zero_(false),
cache_at_eof_(false),
opts_(nullptr),
multithreading_(true)
@@ -217,7 +218,7 @@ FramePtr FFmpegDecoder::RetrieveVideo(const rational &timecode)
return nullptr;
}
int64_t target_ts = Timecode::time_to_timestamp(timecode, avstream_->time_base);
int64_t target_ts = Timecode::time_to_timestamp(timecode, avstream_->time_base) + avstream_->start_time;
bool got_frame = false;
@@ -229,7 +230,11 @@ FramePtr FFmpegDecoder::RetrieveVideo(const rational &timecode)
AVFrame* found_frame = nullptr;
if (cache_at_eof_ && target_ts > cached_frames_.last()->pts) {
if (cache_at_zero_ && target_ts < cached_frames_.first()->pts) {
found_frame = cached_frames_.first();
} else if (cache_at_eof_ && target_ts > cached_frames_.last()->pts) {
found_frame = cached_frames_.last();
@@ -301,6 +306,9 @@ FramePtr FFmpegDecoder::RetrieveVideo(const rational &timecode)
ClearFrameCache();
Seek(seek_ts);
if (seek_ts == 0) {
cache_at_zero_ = true;
}
still_seeking = true;
}
@@ -328,10 +336,13 @@ FramePtr FFmpegDecoder::RetrieveVideo(const rational &timecode)
if (still_seeking) {
// Handle a failure to seek (occurs on some media)
// We'll only be here if the frame cache was emptied earlier
if (ret == AVERROR_EOF || working_frame->pts > target_ts) {
if (!cache_at_zero_ && (ret == AVERROR_EOF || working_frame->pts > target_ts)) {
seek_ts -= second_ts_;
seek_ts = qMax(0LL, seek_ts - second_ts_);
Seek(seek_ts);
if (seek_ts == 0) {
cache_at_zero_ = true;
}
av_frame_free(&working_frame);
continue;
@@ -357,7 +368,11 @@ FramePtr FFmpegDecoder::RetrieveVideo(const rational &timecode)
if (working_frame->pts == target_ts) {
found_frame = working_frame;
} else if (working_frame->pts > target_ts) {
found_frame = cached_frames_.last();
if (cache_at_zero_) {
found_frame = working_frame;
} else {
found_frame = cached_frames_.last();
}
}
}
@@ -999,4 +1014,5 @@ void FFmpegDecoder::ClearFrameCache()
}
cached_frames_.clear();
cache_at_eof_ = false;
cache_at_zero_ = false;
}
+1
View File
@@ -116,6 +116,7 @@ private:
SwsContext* scale_ctx_;
QList<AVFrame*> cached_frames_;
bool cache_at_zero_;
bool cache_at_eof_;
int64_t second_ts_;