From 266fe11af7f3bdc194cfedf92db7352b7b68be97 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 22 Sep 2012 11:35:36 +0100 Subject: Improve transcode job progress reporting. --- src/lib/transcode_job.cc | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'src/lib/transcode_job.cc') diff --git a/src/lib/transcode_job.cc b/src/lib/transcode_job.cc index 652a18441..f4e3d7af9 100644 --- a/src/lib/transcode_job.cc +++ b/src/lib/transcode_job.cc @@ -88,13 +88,30 @@ TranscodeJob::status () const if (!_encoder) { return "0%"; } + + if (_encoder->skipping ()) { + return "skipping frames already encoded"; + } + float const fps = _encoder->current_frames_per_second (); if (fps == 0) { return Job::status (); } - + stringstream s; - s << Job::status () << "; about " << fixed << setprecision (1) << fps << " frames per second."; + + s << Job::status () << "; " << fixed << setprecision (1) << fps << " frames per second"; return s.str (); } + +int +TranscodeJob::remaining_time () const +{ + float fps = _encoder->current_frames_per_second (); + if (fps == 0) { + return 0; + } + + return ((_fs->length - _encoder->last_frame()) / fps); +} -- cgit v1.2.3 From 45698c6bc5cd3a596e7f0c963733d502c11dd854 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 24 Sep 2012 13:40:21 +0100 Subject: Report finished even when the transcode skipped everything. --- src/lib/transcode_job.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib/transcode_job.cc') diff --git a/src/lib/transcode_job.cc b/src/lib/transcode_job.cc index f4e3d7af9..c91058973 100644 --- a/src/lib/transcode_job.cc +++ b/src/lib/transcode_job.cc @@ -89,7 +89,7 @@ TranscodeJob::status () const return "0%"; } - if (_encoder->skipping ()) { + if (_encoder->skipping () && !finished ()) { return "skipping frames already encoded"; } -- cgit v1.2.3 From 82af50304f55a961cba6afefbfa7edd5440bfcc4 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 25 Sep 2012 01:20:58 +0100 Subject: Basic J2K hash checking. --- src/lib/check_hashes_job.cc | 79 +++++++++++++++++++++++++++++++++++++++++++++ src/lib/check_hashes_job.h | 33 +++++++++++++++++++ src/lib/dcp_video_frame.cc | 11 ++++++- src/lib/film.cc | 4 ++- src/lib/transcode_job.cc | 1 - src/lib/util.h | 3 +- src/lib/wscript | 1 + 7 files changed, 127 insertions(+), 5 deletions(-) create mode 100644 src/lib/check_hashes_job.cc create mode 100644 src/lib/check_hashes_job.h (limited to 'src/lib/transcode_job.cc') diff --git a/src/lib/check_hashes_job.cc b/src/lib/check_hashes_job.cc new file mode 100644 index 000000000..87eb40d14 --- /dev/null +++ b/src/lib/check_hashes_job.cc @@ -0,0 +1,79 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include +#include "check_hashes_job.h" +#include "film_state.h" +#include "options.h" +#include "log.h" + +using namespace std; +using namespace boost; + +CheckHashesJob::CheckHashesJob (shared_ptr s, shared_ptr o, Log* l) + : Job (s, o, l) + , _bad (0) +{ + +} + +string +CheckHashesJob::name () const +{ + stringstream s; + s << "Check hashes of " << _fs->name; + return s.str (); +} + +void +CheckHashesJob::run () +{ + _bad = 0; + + for (int i = 0; i < _fs->length; ++i) { + string const j2k_file = _opt->frame_out_path (i, false); + string const hash_file = j2k_file + ".md5"; + + ifstream ref (hash_file.c_str ()); + string hash; + ref >> hash; + + if (hash != md5_digest (j2k_file)) { + _log->log ("Frame " + lexical_cast (i) + " has wrong hash; deleting."); + filesystem::remove (j2k_file); + filesystem::remove (hash_file); + ++_bad; + } + + set_progress (float (i) / _fs->length); + } + + set_progress (1); + set_state (FINISHED_OK); +} + +string +CheckHashesJob::status () const +{ + stringstream s; + s << Job::status () << "; " << _bad << " bad frames found"; + return s.str (); +} diff --git a/src/lib/check_hashes_job.h b/src/lib/check_hashes_job.h new file mode 100644 index 000000000..b59cf031b --- /dev/null +++ b/src/lib/check_hashes_job.h @@ -0,0 +1,33 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "job.h" + +class CheckHashesJob : public Job +{ +public: + CheckHashesJob (boost::shared_ptr s, boost::shared_ptr o, Log* l); + + std::string name () const; + void run (); + std::string status () const; + +private: + int _bad; +}; diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc index 96c40358a..da7133c4b 100644 --- a/src/lib/dcp_video_frame.cc +++ b/src/lib/dcp_video_frame.cc @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -344,8 +345,16 @@ EncodedData::write (shared_ptr opt, int frame) fwrite (_data, 1, _size, f); fclose (f); + string const real_j2k = opt->frame_out_path (frame, false); + /* Rename the file from foo.j2c.tmp to foo.j2c now that it is complete */ - filesystem::rename (tmp_j2k, opt->frame_out_path (frame, false)); + filesystem::rename (tmp_j2k, real_j2k); + + /* Write a file containing the hash */ + string const hash = real_j2k + ".md5"; + ofstream h (hash.c_str()); + h << md5_digest (_data, _size) << "\n"; + h.close (); } /** Send this data to a socket. diff --git a/src/lib/film.cc b/src/lib/film.cc index d1334130e..583a15e19 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -48,6 +48,7 @@ #include "scaler.h" #include "decoder_factory.h" #include "config.h" +#include "check_hashes_job.h" using namespace std; using namespace boost; @@ -544,7 +545,8 @@ Film::make_dcp (bool transcode, int freq) JobManager::instance()->add (shared_ptr (new TranscodeJob (fs, o, log ()))); } } - + + JobManager::instance()->add (shared_ptr (new CheckHashesJob (fs, o, log ()))); JobManager::instance()->add (shared_ptr (new MakeDCPJob (fs, o, log ()))); } diff --git a/src/lib/transcode_job.cc b/src/lib/transcode_job.cc index c91058973..2de6e90ca 100644 --- a/src/lib/transcode_job.cc +++ b/src/lib/transcode_job.cc @@ -78,7 +78,6 @@ TranscodeJob::run () _log->log (s.str ()); throw; - } } diff --git a/src/lib/util.h b/src/lib/util.h index 03d04b852..bc5a00fc4 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -46,14 +46,13 @@ extern double seconds (struct timeval); extern void dvdomatic_setup (); extern std::vector split_at_spaces_considering_quotes (std::string); extern std::string md5_digest (std::string); +extern std::string md5_digest (void const *, int); enum ContentType { STILL, VIDEO }; -extern std::string md5_hash (void const *, int); - /** @class Size * @brief Representation of the size of something */ struct Size diff --git a/src/lib/wscript b/src/lib/wscript index 803ffd9ee..c809226ce 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -8,6 +8,7 @@ def build(bld): obj.source = """ ab_transcode_job.cc ab_transcoder.cc + check_hashes_job.cc config.cc copy_from_dvd_job.cc cross.cc -- cgit v1.2.3 From 922361469072474da4294a90f1436cd0117cb90f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 25 Sep 2012 01:36:53 +0100 Subject: Re-transcode and re-check J2Ks after a bad one is found. --- src/lib/check_hashes_job.cc | 27 ++++++++++++++++++++++++++- src/lib/job.h | 3 ++- src/lib/job_manager.cc | 12 ++++++++++-- src/lib/job_manager.h | 1 + src/lib/transcode_job.cc | 2 +- 5 files changed, 40 insertions(+), 5 deletions(-) (limited to 'src/lib/transcode_job.cc') diff --git a/src/lib/check_hashes_job.cc b/src/lib/check_hashes_job.cc index 87eb40d14..5a927f752 100644 --- a/src/lib/check_hashes_job.cc +++ b/src/lib/check_hashes_job.cc @@ -24,6 +24,9 @@ #include "film_state.h" #include "options.h" #include "log.h" +#include "job_manager.h" +#include "ab_transcode_job.h" +#include "transcode_job.h" using namespace std; using namespace boost; @@ -66,6 +69,19 @@ CheckHashesJob::run () set_progress (float (i) / _fs->length); } + if (_bad) { + shared_ptr tc; + + if (_fs->dcp_ab) { + tc.reset (new ABTranscodeJob (_fs, _opt, _log)); + } else { + tc.reset (new TranscodeJob (_fs, _opt, _log)); + } + + JobManager::instance()->add_after (shared_from_this(), tc); + JobManager::instance()->add_after (tc, shared_ptr (new CheckHashesJob (_fs, _opt, _log))); + } + set_progress (1); set_state (FINISHED_OK); } @@ -74,6 +90,15 @@ string CheckHashesJob::status () const { stringstream s; - s << Job::status () << "; " << _bad << " bad frames found"; + s << Job::status (); + if (overall_progress() > 0) { + if (_bad == 0) { + s << "; no bad frames found"; + } else if (_bad == 1) { + s << "; 1 bad frame found"; + } else { + s << "; " << _bad << " bad frames found"; + } + } return s.str (); } diff --git a/src/lib/job.h b/src/lib/job.h index fee887b42..b39130479 100644 --- a/src/lib/job.h +++ b/src/lib/job.h @@ -26,6 +26,7 @@ #include #include +#include #include class Log; @@ -35,7 +36,7 @@ class Options; /** @class Job * @brief A parent class to represent long-running tasks which are run in their own thread. */ -class Job +class Job : public boost::enable_shared_from_this { public: Job (boost::shared_ptr s, boost::shared_ptr o, Log* l); diff --git a/src/lib/job_manager.cc b/src/lib/job_manager.cc index 93fdbd27a..a166b5924 100644 --- a/src/lib/job_manager.cc +++ b/src/lib/job_manager.cc @@ -41,15 +41,23 @@ void JobManager::add (shared_ptr j) { boost::mutex::scoped_lock lm (_mutex); - _jobs.push_back (j); } +void +JobManager::add_after (shared_ptr after, shared_ptr j) +{ + boost::mutex::scoped_lock lm (_mutex); + list >::iterator i = find (_jobs.begin(), _jobs.end(), after); + assert (i != _jobs.end ()); + ++i; + _jobs.insert (i, j); +} + list > JobManager::get () const { boost::mutex::scoped_lock lm (_mutex); - return _jobs; } diff --git a/src/lib/job_manager.h b/src/lib/job_manager.h index f2f5e0057..d1d33cfc2 100644 --- a/src/lib/job_manager.h +++ b/src/lib/job_manager.h @@ -38,6 +38,7 @@ class JobManager public: void add (boost::shared_ptr); + void add_after (boost::shared_ptr after, boost::shared_ptr j); std::list > get () const; bool work_to_do () const; diff --git a/src/lib/transcode_job.cc b/src/lib/transcode_job.cc index 2de6e90ca..9113593f0 100644 --- a/src/lib/transcode_job.cc +++ b/src/lib/transcode_job.cc @@ -89,7 +89,7 @@ TranscodeJob::status () const } if (_encoder->skipping () && !finished ()) { - return "skipping frames already encoded"; + return "skipping already-encoded frames"; } -- cgit v1.2.3