Remove another use of fstream.
[dcpomatic.git] / src / lib / writer.cc
index 5e8fb5b7a020bdf4be553d8bb65a005e80b5ac8f..f4128e6c573d6b65e81480b699fdb8626e595ee0 100644 (file)
 #include "audio_mapping.h"
 #include "config.h"
 #include "job.h"
+#include "cross.h"
 
 #include "i18n.h"
 
 using std::make_pair;
 using std::pair;
 using std::string;
-using std::ifstream;
 using std::list;
 using std::cout;
 using boost::shared_ptr;
+using boost::weak_ptr;
 
 int const Writer::_maximum_frames_in_memory = 8;
 
-Writer::Writer (shared_ptr<const Film> f, shared_ptr<Job> j)
+Writer::Writer (shared_ptr<const Film> f, weak_ptr<Job> j)
        : _film (f)
        , _job (j)
        , _first_nonexistant_frame (0)
@@ -65,9 +66,13 @@ Writer::Writer (shared_ptr<const Film> f, shared_ptr<Job> j)
 {
        /* Remove any old DCP */
        boost::filesystem::remove_all (_film->dir (_film->dcp_name ()));
-       
+
+       shared_ptr<Job> job = _job.lock ();
+       assert (job);
+
+       job->sub (_("Checking existing image data"));
        check_existing_picture_mxf ();
-       
+
        /* Create our picture asset in a subdirectory, named according to those
           film's parameters which affect the video output.  We will hard-link
           it into the DCP later.
@@ -80,7 +85,7 @@ Writer::Writer (shared_ptr<const Film> f, shared_ptr<Job> j)
        }
 
        _picture_asset->set_edit_rate (_film->video_frame_rate ());
-       _picture_asset->set_size (_film->container()->size (_film->full_frame ()));
+       _picture_asset->set_size (fit_ratio_within (_film->container()->ratio(), _film->full_frame ()));
 
        if (_film->encrypted ()) {
                _picture_asset->set_key (_film->key ());
@@ -101,7 +106,7 @@ Writer::Writer (shared_ptr<const Film> f, shared_ptr<Job> j)
 
        _thread = new boost::thread (boost::bind (&Writer::thread, this));
 
-       _job->descend (0.9);
+       job->sub (_("Encoding image data"));
 }
 
 void
@@ -136,8 +141,9 @@ Writer::fake_write (int frame, Eyes eyes)
 {
        boost::mutex::scoped_lock lock (_mutex);
 
-       ifstream ifi (_film->info_path (frame, eyes).c_str());
+       FILE* ifi = fopen_boost (_film->info_path (frame, eyes), "r");
        libdcp::FrameInfo info (ifi);
+       fclose (ifi);
        
        QueueItem qi;
        qi.type = QueueItem::FAKE;
@@ -266,7 +272,9 @@ try
                        _last_written_eyes = qi.eyes;
                        
                        if (_film->length()) {
-                               _job->set_progress (
+                               shared_ptr<Job> job = _job.lock ();
+                               assert (job);
+                               job->set_progress (
                                        float (_full_written + _fake_written + _repeat_written) / _film->time_to_video_frames (_film->length())
                                        );
                        }
@@ -381,17 +389,14 @@ 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 ();
+       shared_ptr<Job> job = _job.lock ();
+       assert (job);
 
-       _job->descend (0.1);
-       _picture_asset->compute_digest (boost::bind (&Job::set_progress, _job.get(), _1));
-       _job->ascend ();
+       job->sub (_("Computing image digest"));
+       _picture_asset->compute_digest (boost::bind (&Job::set_progress, job.get(), _1, false));
 
-       _job->descend (0.1);
-       _sound_asset->compute_digest (boost::bind (&Job::set_progress, _job.get(), _1));
-       _job->ascend ();
+       job->sub (_("Computing audio digest"));
+       _sound_asset->compute_digest (boost::bind (&Job::set_progress, job.get(), _1, false));
 
        libdcp::XMLMetadata meta = Config::instance()->dcp_metadata ();
        meta.set_issue_date_now ();
@@ -426,15 +431,20 @@ bool
 Writer::check_existing_picture_mxf_frame (FILE* mxf, int f, Eyes eyes)
 {
        /* Read the frame info as written */
-       ifstream ifi (_film->info_path (f, eyes).c_str());
+       FILE* ifi = fopen_boost (_film->info_path (f, eyes), "r");
        libdcp::FrameInfo info (ifi);
+       fclose (ifi);
        if (info.size == 0) {
                _film->log()->log (String::compose ("Existing frame %1 has no info file", f));
                return false;
        }
        
        /* Read the data from the MXF and hash it */
+#ifdef DCPOMATIC_WINDOWS
+       _fseeki64 (mxf, info.offset, SEEK_SET);
+#else  
        fseek (mxf, info.offset, SEEK_SET);
+#endif 
        EncodedData data (info.size);
        size_t const read = fread (data.data(), 1, data.size(), mxf);
        if (read != static_cast<size_t> (data.size ())) {
@@ -464,8 +474,18 @@ Writer::check_existing_picture_mxf ()
                return;
        }
 
+       int N = 0;
+       for (boost::filesystem::directory_iterator i (_film->info_dir ()); i != boost::filesystem::directory_iterator (); ++i) {
+               ++N;
+       }
+
        while (1) {
 
+               shared_ptr<Job> job = _job.lock ();
+               assert (job);
+
+               job->set_progress (float (_first_nonexistant_frame) / N);
+
                if (_film->three_d ()) {
                        if (!check_existing_picture_mxf_frame (mxf, _first_nonexistant_frame, EYES_LEFT)) {
                                break;