ffmpeg: allow decoders immediate access to frames even while indexing
Previously, FFmpeg decoders needed to wait for the initial index to finish before they could retrieve frames. Now they can retrieve frames while the index is occurring, provided the appropriate frame has already been indexed (if not, the retrieve will need to wait still).
This commit is contained in:
@@ -140,6 +140,11 @@ StreamID Stream::ToID() const
|
||||
return StreamID(footage_->filename(), index_);
|
||||
}
|
||||
|
||||
QMutex* Stream::index_process_lock()
|
||||
{
|
||||
return &index_process_lock_;
|
||||
}
|
||||
|
||||
void Stream::FootageSetEvent(Footage*)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ public:
|
||||
|
||||
StreamID ToID() const;
|
||||
|
||||
QMutex index_lock_;
|
||||
QMutex* index_process_lock();
|
||||
|
||||
protected:
|
||||
virtual void FootageSetEvent(Footage*);
|
||||
@@ -112,6 +112,9 @@ protected:
|
||||
|
||||
virtual void SaveCustomParameters(QXmlStreamWriter* writer) const;
|
||||
|
||||
signals:
|
||||
void IndexChanged();
|
||||
|
||||
private:
|
||||
Footage* footage_;
|
||||
|
||||
@@ -125,6 +128,8 @@ private:
|
||||
|
||||
bool enabled_;
|
||||
|
||||
QMutex index_process_lock_;
|
||||
|
||||
};
|
||||
|
||||
using StreamPtr = std::shared_ptr<Stream>;
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
#include "videostream.h"
|
||||
|
||||
#include <QFile>
|
||||
|
||||
VideoStream::VideoStream()
|
||||
{
|
||||
set_type(kVideo);
|
||||
@@ -41,3 +43,92 @@ void VideoStream::set_frame_rate(const rational &frame_rate)
|
||||
{
|
||||
frame_rate_ = frame_rate;
|
||||
}
|
||||
|
||||
int64_t VideoStream::get_closest_timestamp_in_frame_index(const int64_t &ts)
|
||||
{
|
||||
QMutexLocker locker(&index_access_lock_);
|
||||
|
||||
if (ts <= 0) {
|
||||
return frame_index_.first();
|
||||
}
|
||||
|
||||
// Use index to find closest frame in file
|
||||
for (int i=0;i<frame_index_.size();i++) {
|
||||
int64_t this_ts = frame_index_.at(i);
|
||||
|
||||
if (this_ts == ts) {
|
||||
return ts;
|
||||
} else if (this_ts > ts) {
|
||||
return frame_index_.at(i - 1);
|
||||
}
|
||||
}
|
||||
|
||||
return frame_index_.last();
|
||||
}
|
||||
|
||||
void VideoStream::clear_frame_index()
|
||||
{
|
||||
QMutexLocker locker(&index_access_lock_);
|
||||
|
||||
frame_index_.clear();
|
||||
}
|
||||
|
||||
void VideoStream::append_frame_index(const int64_t &ts)
|
||||
{
|
||||
QMutexLocker locker(&index_access_lock_);
|
||||
|
||||
frame_index_.append(ts);
|
||||
}
|
||||
|
||||
bool VideoStream::is_frame_index_empty()
|
||||
{
|
||||
QMutexLocker locker(&index_access_lock_);
|
||||
|
||||
return frame_index_.isEmpty();
|
||||
}
|
||||
|
||||
int64_t VideoStream::last_frame_index_timestamp()
|
||||
{
|
||||
QMutexLocker locker(&index_access_lock_);
|
||||
|
||||
return frame_index_.last();
|
||||
}
|
||||
|
||||
bool VideoStream::load_frame_index(const QString &s)
|
||||
{
|
||||
// Load index from file
|
||||
QFile index_file(s);
|
||||
|
||||
if (index_file.exists() && index_file.open(QFile::ReadOnly)) {
|
||||
QMutexLocker locker(&index_access_lock_);
|
||||
|
||||
// Resize based on filesize
|
||||
frame_index_.resize(static_cast<size_t>(index_file.size()) / sizeof(int64_t));
|
||||
|
||||
// Read frame index into vector
|
||||
index_file.read(reinterpret_cast<char*>(frame_index_.data()),
|
||||
index_file.size());
|
||||
|
||||
index_file.close();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VideoStream::save_frame_index(const QString &s)
|
||||
{
|
||||
QFile index_file(s);
|
||||
|
||||
if (index_file.open(QFile::WriteOnly)) {
|
||||
// Write index in binary
|
||||
QMutexLocker locker(&index_access_lock_);
|
||||
|
||||
index_file.write(reinterpret_cast<const char*>(frame_index_.constData()),
|
||||
frame_index_.size() * static_cast<int>(sizeof(int64_t)));
|
||||
|
||||
index_file.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -38,9 +38,22 @@ public:
|
||||
const rational& frame_rate() const;
|
||||
void set_frame_rate(const rational& frame_rate);
|
||||
|
||||
int64_t get_closest_timestamp_in_frame_index(const int64_t& ts);
|
||||
void clear_frame_index();
|
||||
void append_frame_index(const int64_t& ts);
|
||||
bool is_frame_index_empty();
|
||||
int64_t last_frame_index_timestamp();
|
||||
|
||||
bool load_frame_index(const QString& s);
|
||||
bool save_frame_index(const QString& s);
|
||||
|
||||
private:
|
||||
rational frame_rate_;
|
||||
|
||||
QVector<int64_t> frame_index_;
|
||||
|
||||
QMutex index_access_lock_;
|
||||
|
||||
};
|
||||
|
||||
using VideoStreamPtr = std::shared_ptr<VideoStream>;
|
||||
|
||||
Reference in New Issue
Block a user