try to index media immediately on import
Since indexing is supplemental, it can be made a background task that can occur at more or less any time. So we run it as soon as possible.
This commit is contained in:
@@ -26,6 +26,8 @@
|
||||
|
||||
#include "codec/ffmpeg/ffmpegdecoder.h"
|
||||
#include "codec/oiio/oiiodecoder.h"
|
||||
#include "task/index/index.h"
|
||||
#include "task/taskmanager.h"
|
||||
|
||||
Decoder::Decoder() :
|
||||
open_(false),
|
||||
@@ -126,6 +128,14 @@ bool Decoder::ProbeMedia(Footage *f)
|
||||
|
||||
// FIXME: Cache the results so we don't have to probe if this media is added a second time
|
||||
|
||||
// Start an index task
|
||||
foreach (StreamPtr stream, f->streams()) {
|
||||
qDebug() << "Starting index task on" << stream->footage()->filename() << stream->index();
|
||||
|
||||
IndexTask* index_task = new IndexTask(stream);
|
||||
TaskManager::instance()->AddTask(index_task);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -161,3 +171,7 @@ void Decoder::Conform(const AudioRenderingParams ¶ms)
|
||||
qCritical() << "Conform called on an audio decoder that does not have a handler for it:" << id();
|
||||
abort();
|
||||
}
|
||||
|
||||
void Decoder::Index()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -219,6 +219,17 @@ public:
|
||||
*/
|
||||
virtual void Conform(const AudioRenderingParams& params);
|
||||
|
||||
/**
|
||||
* @brief Create an index for this media
|
||||
*
|
||||
* Indexes are used to improve speed and reliability of imported media. Calling Retrieve() will automatically check
|
||||
* for an index and create one if it doesn't exist.
|
||||
*
|
||||
* Indexing is slow so it's recommended to do it in a background thread. Index() must be called while the Decoder is
|
||||
* open, and does not automatically call Open() and Close() the Decoder. The caller must call thse manually.
|
||||
*/
|
||||
virtual void Index();
|
||||
|
||||
protected:
|
||||
bool open_;
|
||||
|
||||
|
||||
@@ -62,6 +62,11 @@ bool FFmpegDecoder::Open()
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!stream()) {
|
||||
Error(QStringLiteral("Tried to open a decoder with no footage stream set"));
|
||||
return false;
|
||||
}
|
||||
|
||||
int error_code;
|
||||
|
||||
// Convert QString to a C string
|
||||
@@ -344,7 +349,7 @@ FramePtr FFmpegDecoder::RetrieveAudio(const rational &timecode, const rational &
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ValidateIndex();
|
||||
Index();
|
||||
|
||||
Conform(params);
|
||||
|
||||
@@ -437,7 +442,7 @@ void FFmpegDecoder::Conform(const AudioRenderingParams ¶ms)
|
||||
return;
|
||||
}
|
||||
|
||||
ValidateIndex();
|
||||
Index();
|
||||
|
||||
// Get indexed WAV file
|
||||
WaveInput input(GetIndexFilename());
|
||||
@@ -659,7 +664,7 @@ bool FFmpegDecoder::Probe(Footage *f)
|
||||
Open();
|
||||
|
||||
// Use index to find duration
|
||||
ValidateIndex();
|
||||
Index();
|
||||
|
||||
// Use last frame index as the duration
|
||||
// FIXME: Does this skip the last frame?
|
||||
@@ -706,17 +711,25 @@ void FFmpegDecoder::Index()
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset state
|
||||
Seek(0);
|
||||
stream()->index_lock_.lock();
|
||||
|
||||
if (!LoadIndex()) {
|
||||
|
||||
// Reset state
|
||||
Seek(0);
|
||||
|
||||
if (avstream_->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||
IndexVideo(pkt_, frame_);
|
||||
} else if (avstream_->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||
IndexAudio(pkt_, frame_);
|
||||
}
|
||||
|
||||
// Reset state
|
||||
Seek(0);
|
||||
|
||||
if (avstream_->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||
IndexVideo(pkt_, frame_);
|
||||
} else if (avstream_->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||
IndexAudio(pkt_, frame_);
|
||||
}
|
||||
|
||||
// Reset state
|
||||
Seek(0);
|
||||
stream()->index_lock_.unlock();
|
||||
}
|
||||
|
||||
QString FFmpegDecoder::GetIndexFilename()
|
||||
@@ -756,17 +769,6 @@ QString FFmpegDecoder::GetConformedFilename(const AudioRenderingParams ¶ms)
|
||||
return index_fn;
|
||||
}
|
||||
|
||||
void FFmpegDecoder::ValidateIndex()
|
||||
{
|
||||
stream()->index_lock_.lock();
|
||||
|
||||
if (!LoadIndex()) {
|
||||
Index();
|
||||
}
|
||||
|
||||
stream()->index_lock_.unlock();
|
||||
}
|
||||
|
||||
bool FFmpegDecoder::LoadIndex()
|
||||
{
|
||||
switch (avstream_->codecpar->codec_type) {
|
||||
@@ -991,7 +993,7 @@ int64_t FFmpegDecoder::GetClosestTimestampInIndex(const int64_t &ts)
|
||||
{
|
||||
// Index now if we haven't already
|
||||
if (frame_index_.isEmpty()) {
|
||||
ValidateIndex();
|
||||
Index();
|
||||
}
|
||||
|
||||
if (frame_index_.isEmpty()) {
|
||||
|
||||
@@ -92,18 +92,7 @@ private:
|
||||
*/
|
||||
int GetFrame(AVPacket* pkt, AVFrame* frame);
|
||||
|
||||
/**
|
||||
* @brief Create an index for this media
|
||||
*
|
||||
* Indexes are used to improve speed and reliability of imported media. Calling Retrieve() will automatically check
|
||||
* for an index and create one if it doesn't exist.
|
||||
*
|
||||
* Indexing is slow so it's recommended to do it in a background thread. Index() must be called while the Decoder is
|
||||
* open, and does not automatically call Open() and Close() the Decoder. The caller must call thse manually.
|
||||
*
|
||||
* FIXME: This should perhaps become a common function for the base Decoder class
|
||||
*/
|
||||
void Index();
|
||||
virtual void Index() override;
|
||||
|
||||
/**
|
||||
* @brief Returns the filename for the index
|
||||
@@ -117,8 +106,6 @@ private:
|
||||
*/
|
||||
QString GetConformedFilename(const AudioRenderingParams ¶ms);
|
||||
|
||||
void ValidateIndex();
|
||||
|
||||
/**
|
||||
* @brief Used internally to load a frame index into frame_index_
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user