Better progress reporting during MXF hashing (#184).
authorCarl Hetherington <cth@carlh.net>
Thu, 29 Aug 2013 13:25:31 +0000 (14:25 +0100)
committerCarl Hetherington <cth@carlh.net>
Thu, 29 Aug 2013 13:25:31 +0000 (14:25 +0100)
ChangeLog
src/lib/encoder.cc
src/lib/encoder.h
src/lib/transcode_job.cc
src/lib/transcoder.cc
src/lib/transcoder.h
src/lib/writer.cc

index f88d29d5681e468853ff32552dcf9816debe6ed9..54fdc10fa3c9a2bcdba3b5e823fa82b68f9f63bb 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
 2013-08-29  Carl Hetherington  <cth@carlh.net>
 
+       * Fix stuck-at-99% progress meters (#184).
+
        * Version 1.01beta1 released.
 
 2013-08-29  Carl Hetherington  <cth@carlh.net>
index ea175f1f43cdc30b3e9cdad8ab2429337e6b94fb..35ebfb52e1fc089d88383e5d0558b6719fa4f3c9 100644 (file)
@@ -52,6 +52,7 @@ Encoder::Encoder (shared_ptr<const Film> f, shared_ptr<Job> j)
        : _film (f)
        , _job (j)
        , _video_frames_out (0)
+       , _state (TRANSCODING)
        , _terminate (false)
 {
        _have_a_real_frame[EYES_BOTH] = false;
@@ -125,6 +126,11 @@ Encoder::process_end ()
                }
        }
 
+       {
+               boost::mutex::scoped_lock lm (_state_mutex);
+               _state = HASHING;
+       }
+               
        _writer->finish ();
        _writer.reset ();
 }      
@@ -135,7 +141,7 @@ Encoder::process_end ()
 float
 Encoder::current_encoding_rate () const
 {
-       boost::mutex::scoped_lock lock (_history_mutex);
+       boost::mutex::scoped_lock lock (_state_mutex);
        if (int (_time_history.size()) < _history_size) {
                return 0;
        }
@@ -150,7 +156,7 @@ Encoder::current_encoding_rate () const
 int
 Encoder::video_frames_out () const
 {
-       boost::mutex::scoped_lock (_history_mutex);
+       boost::mutex::scoped_lock (_state_mutex);
        return _video_frames_out;
 }
 
@@ -160,7 +166,7 @@ Encoder::video_frames_out () const
 void
 Encoder::frame_done ()
 {
-       boost::mutex::scoped_lock lock (_history_mutex);
+       boost::mutex::scoped_lock lock (_state_mutex);
        
        struct timeval tv;
        gettimeofday (&tv, 0);
index 44134e568bf819fabeeb3b3f09a3d72f57eb7e17..e9b30df9e558cbf60c00f54e612869d7e2887b09 100644 (file)
@@ -77,6 +77,16 @@ public:
        float current_encoding_rate () const;
        int video_frames_out () const;
 
+       enum State {
+               TRANSCODING,
+               HASHING
+       };
+
+       State state () const {
+               boost::mutex::scoped_lock lm (_state_mutex);
+               return _state;
+       }
+
 private:
        
        void frame_done ();
@@ -88,8 +98,8 @@ private:
        boost::shared_ptr<const Film> _film;
        boost::shared_ptr<Job> _job;
 
-       /** Mutex for _time_history and _last_frame */
-       mutable boost::mutex _history_mutex;
+       /** Mutex for _time_history, _last_frame and _state */
+       mutable boost::mutex _state_mutex;
        /** List of the times of completion of the last _history_size frames;
            first is the most recently completed.
        */
@@ -99,6 +109,7 @@ private:
 
        /** Number of video frames written for the DCP so far */
        int _video_frames_out;
+       State _state;
 
        bool _have_a_real_frame[EYES_COUNT];
        bool _terminate;
index 6d5edd7c060c662dc404445c1e3ed1a1175d4ace..c9ec2053d46353a500cd6c4178af395a6c303906 100644 (file)
@@ -91,7 +91,12 @@ TranscodeJob::status () const
        s << Job::status ();
 
        if (!finished ()) {
-               s << N_("; ") << fixed << setprecision (1) << fps << N_(" ") << _("frames per second");
+               if (_transcoder->state() == Encoder::TRANSCODING) {
+                       s << "; " << fixed << setprecision (1) << fps << N_(" ") << _("frames per second");
+               } else {
+                       /* TRANSLATORS: this means `computing a hash' as in a digest of a block of data */
+                       s << "; " << _("hashing");
+               }
        }
        
        return s.str ();
index 715a158db20b5b8ffe19473cececdec01235f364..63ba77939f2cf7ca033286c6ee88a575fa698aa4 100644 (file)
@@ -90,3 +90,9 @@ Transcoder::video_frames_out () const
 {
        return _encoder->video_frames_out ();
 }
+
+Encoder::State
+Transcoder::state () const
+{
+       return _encoder->state ();
+}
index 007065b658cd7240f15001f1361f549aa1378493..7bf214a88de6ccbbb3b53bacc43fb8c8791de410 100644 (file)
 */
 
 #include "types.h"
-
-/** @file  src/transcoder.h
- *
- *  A decoder is selected according to the content type, and the encoder can be specified
- *  as a parameter to the constructor.
- */
+#include "encoder.h"
 
 class Film;
 class Job;
@@ -31,11 +26,7 @@ class Encoder;
 class VideoFilter;
 class Player;
 
-/** @class Transcoder
- *
- *  A decoder is selected according to the content type, and the encoder can be specified
- *  as a parameter to the constructor.
- */
+/** @class Transcoder */
 class Transcoder : public boost::noncopyable
 {
 public:
@@ -47,6 +38,7 @@ public:
        void go ();
 
        float current_encoding_rate () const;
+       Encoder::State state () const;
        int video_frames_out () const;
 
 private:
index 2e0ffd8336ddc2583bba40b687d23f17e60576a4..5f94d5d6bc65e1f95f13ee730a5af12c579ee286 100644 (file)
@@ -110,6 +110,8 @@ Writer::Writer (shared_ptr<const Film> f, shared_ptr<Job> j)
        _sound_asset_writer = _sound_asset->start_write (_film->interop ());
 
        _thread = new boost::thread (boost::bind (&Writer::thread, this));
+
+       _job->descend (0.9);
 }
 
 void
@@ -389,6 +391,18 @@ Writer::finish ()
                                                         )
                               ));
 
+       /* Compute the digests for the assets now so that we can keep track of progress.
+          We did _job->descend (0.9) in our constructor */
+       _job->ascend ();
+
+       _job->descend (0.1);
+       _picture_asset->compute_digest (boost::bind (&Job::set_progress, _job.get(), _1));
+       _job->ascend ();
+
+       _job->descend (0.1);
+       _sound_asset->compute_digest (boost::bind (&Job::set_progress, _job.get(), _1));
+       _job->ascend ();
+
        libdcp::XMLMetadata meta = Config::instance()->dcp_metadata ();
        meta.set_issue_date_now ();
        dcp.write_xml (_film->interop (), meta);