Show progress information when transcoding files to copy to a device

This commit is contained in:
David Sansome 2010-08-30 11:36:40 +00:00
parent 2808ce4d34
commit 728925097d
4 changed files with 78 additions and 12 deletions

View File

@ -26,6 +26,7 @@
#include <boost/bind.hpp>
const int Organise::kBatchSize = 10;
const int Organise::kTranscodeProgressInterval = 500;
Organise::Organise(TaskManager* task_manager,
boost::shared_ptr<MusicStorage> 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<QString, float> 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();
}
}

View File

@ -17,6 +17,7 @@
#ifndef ORGANISE_H
#define ORGANISE_H
#include <QBasicTimer>
#include <QObject>
#include <QTemporaryFile>
@ -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<Task> tasks_pending_;
QMap<QString, Task> tasks_transcoding_;
int tasks_complete_;
bool started_;
int task_id_;
int progress_;
int song_progress_;
int current_copy_progress_;
QStringList files_with_errors_;
};

View File

@ -470,3 +470,23 @@ void Transcoder::Cancel() {
it = current_jobs_.erase(it);
}
}
QMap<QString, float> Transcoder::GetProgress() const {
QMap<QString, float> ret;
foreach (boost::shared_ptr<JobState> 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;
}

View File

@ -58,12 +58,14 @@ class Transcoder : public QObject {
static Song::FileType PickBestFormat(QList<Song::FileType> 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<QString, float> GetProgress() const;
int QueuedJobsCount() const { return queued_jobs_.count(); }
public slots:
void Start();
void Cancel();