From 728925097d37d92fb9a166b92c473b02ba4fa1a7 Mon Sep 17 00:00:00 2001 From: David Sansome Date: Mon, 30 Aug 2010 11:36:40 +0000 Subject: [PATCH] Show progress information when transcoding files to copy to a device --- src/core/organise.cpp | 49 ++++++++++++++++++++++++++++++----- src/core/organise.h | 17 +++++++++--- src/transcoder/transcoder.cpp | 20 ++++++++++++++ src/transcoder/transcoder.h | 4 ++- 4 files changed, 78 insertions(+), 12 deletions(-) diff --git a/src/core/organise.cpp b/src/core/organise.cpp index 4d2961bf5..6faeaf72c 100644 --- a/src/core/organise.cpp +++ b/src/core/organise.cpp @@ -26,6 +26,7 @@ #include const int Organise::kBatchSize = 10; +const int Organise::kTranscodeProgressInterval = 500; Organise::Organise(TaskManager* task_manager, boost::shared_ptr destination, @@ -43,8 +44,7 @@ Organise::Organise(TaskManager* task_manager, transcode_suffix_(1), started_(false), task_id_(0), - progress_(0), - song_progress_(0) + current_copy_progress_(0) { original_thread_ = thread(); @@ -82,6 +82,7 @@ void Organise::ProcessSomeFiles() { if (!tasks_transcoding_.isEmpty()) { // Just wait - FileTranscoded will start us off again in a little while qDebug() << "Waiting for transcoding jobs"; + transcode_progress_timer_.start(kTranscodeProgressInterval, this); return; } @@ -178,7 +179,8 @@ void Organise::ProcessSomeFiles() { job.metadata_ = song; job.overwrite_ = overwrite_; job.remove_original_ = !copy_; - job.progress_ = boost::bind(&Organise::SetSongProgress, this, _1); + job.progress_ = boost::bind(&Organise::SetSongProgress, + this, _1, !task.transcoded_filename_.isEmpty()); if (!destination_->CopyToStorage(job)) { files_with_errors_ << task.filename_; @@ -188,7 +190,7 @@ void Organise::ProcessSomeFiles() { if (!task.transcoded_filename_.isEmpty()) QFile::remove(task.transcoded_filename_); - progress_++; + tasks_complete_++; } SetSongProgress(0); @@ -226,19 +228,44 @@ Song::FileType Organise::CheckTranscode(Song::FileType original_type) const { return Song::Type_Unknown; } -void Organise::SetSongProgress(float progress) { - song_progress_ = qBound(0, int(progress * 100), 99); +void Organise::SetSongProgress(float progress, bool transcoded) { + const int max = transcoded ? 50 : 100; + current_copy_progress_ = qBound(0, int(progress * max), max-1); UpdateProgress(); } void Organise::UpdateProgress() { - const int progress = progress_ * 100 + song_progress_; const int total = task_count_ * 100; + + // Update transcoding progress + QMap transcode_progress = transcoder_->GetProgress(); + foreach (const QString& filename, transcode_progress.keys()) { + if (!tasks_transcoding_.contains(filename)) + continue; + tasks_transcoding_[filename].transcode_progress_ = transcode_progress[filename]; + } + + // Count the progress of all tasks that are in the queue. Files that need + // transcoding total 50 for the transcode and 50 for the copy, files that + // only need to be copied total 100. + int progress = tasks_complete_ * 100; + + foreach (const Task& task, tasks_pending_) { + progress += qBound(0, int(task.transcode_progress_ * 50), 50); + } + foreach (const Task& task, tasks_transcoding_.values()) { + progress += qBound(0, int(task.transcode_progress_ * 50), 50); + } + + // Add the progress of the track that's currently copying + progress += current_copy_progress_; + task_manager_->SetTaskProgress(task_id_, progress, total); } void Organise::FileTranscoded(const QString& filename, bool success) { qDebug() << "File finished" << filename << success; + transcode_progress_timer_.stop(); Task task = tasks_transcoding_.take(filename); if (!success) { @@ -254,3 +281,11 @@ QString Organise::FiddleFileExtension(const QString& filename, const QString& ne return filename.section('.', 0, -2) + "." + new_extension; return filename + "." + new_extension; } + +void Organise::timerEvent(QTimerEvent* e) { + QObject::timerEvent(e); + + if (e->timerId() == transcode_progress_timer_.timerId()) { + UpdateProgress(); + } +} diff --git a/src/core/organise.h b/src/core/organise.h index f2d050672..0d0285bc5 100644 --- a/src/core/organise.h +++ b/src/core/organise.h @@ -17,6 +17,7 @@ #ifndef ORGANISE_H #define ORGANISE_H +#include #include #include @@ -38,18 +39,22 @@ public: const QStringList& files, bool eject_after); static const int kBatchSize; + static const int kTranscodeProgressInterval; void Start(); signals: void Finished(const QStringList& files_with_errors); +protected: + void timerEvent(QTimerEvent* e); + private slots: void ProcessSomeFiles(); void FileTranscoded(const QString& filename, bool success); private: - void SetSongProgress(float progress); + void SetSongProgress(float progress, bool transcoded = false); void UpdateProgress(); Song::FileType CheckTranscode(Song::FileType original_type) const; @@ -57,9 +62,12 @@ private: private: struct Task { - explicit Task(const QString& filename = QString()) : filename_(filename) {} + explicit Task(const QString& filename = QString()) + : filename_(filename), transcode_progress_(0.0) {} QString filename_; + + float transcode_progress_; QString transcoded_filename_; QString new_extension_; Song::FileType new_filetype_; @@ -78,17 +86,18 @@ private: const bool eject_after_; int task_count_; + QBasicTimer transcode_progress_timer_; QTemporaryFile transcode_temp_name_; int transcode_suffix_; QList tasks_pending_; QMap tasks_transcoding_; + int tasks_complete_; bool started_; int task_id_; - int progress_; - int song_progress_; + int current_copy_progress_; QStringList files_with_errors_; }; diff --git a/src/transcoder/transcoder.cpp b/src/transcoder/transcoder.cpp index 684e80c2a..987412053 100644 --- a/src/transcoder/transcoder.cpp +++ b/src/transcoder/transcoder.cpp @@ -470,3 +470,23 @@ void Transcoder::Cancel() { it = current_jobs_.erase(it); } } + +QMap Transcoder::GetProgress() const { + QMap ret; + + foreach (boost::shared_ptr state, current_jobs_) { + if (!state->pipeline_) + continue; + + gint64 position = 0; + gint64 duration = 0; + GstFormat format = GST_FORMAT_TIME; + + gst_element_query_position(state->pipeline_.get(), &format, &position); + gst_element_query_duration(state->pipeline_.get(), &format, &duration); + + ret[state->job_.input] = float(position) / duration; + } + + return ret; +} diff --git a/src/transcoder/transcoder.h b/src/transcoder/transcoder.h index 9e4edf8cd..278261a17 100644 --- a/src/transcoder/transcoder.h +++ b/src/transcoder/transcoder.h @@ -58,12 +58,14 @@ class Transcoder : public QObject { static Song::FileType PickBestFormat(QList supported); int max_threads() const { return max_threads_; } - void set_max_threads(int count) { max_threads_ = count; } void AddJob(const QString& input, const TranscoderPreset& preset, const QString& output = QString()); + QMap GetProgress() const; + int QueuedJobsCount() const { return queued_jobs_.count(); } + public slots: void Start(); void Cancel();