Merge branch 'master' into fix-early-audio-take2
[dcpomatic.git] / src / lib / encoder.cc
index d4a27d01b5384f1fee2ced8133001b01b1184e43..7b338407eae7765c3bd7aac7bb5fd519b45675a7 100644 (file)
@@ -233,9 +233,9 @@ Encoder::frame_done ()
 void
 Encoder::process_video (shared_ptr<Image> image, bool same, boost::shared_ptr<Subtitle> sub)
 {
-       DCPFrameRate dfr (_film->frames_per_second ());
+       FrameRateConversion frc (_film->source_frame_rate(), _film->dcp_frame_rate());
        
-       if (dfr.skip && (_video_frames_in % 2)) {
+       if (frc.skip && (_video_frames_in % 2)) {
                ++_video_frames_in;
                return;
        }
@@ -244,9 +244,9 @@ Encoder::process_video (shared_ptr<Image> image, bool same, boost::shared_ptr<Su
 
        /* Wait until the queue has gone down a bit */
        while (_queue.size() >= _threads.size() * 2 && !_terminate) {
-               TIMING (_("decoder sleeps with queue of %1"), _queue.size());
+               TIMING ("decoder sleeps with queue of %1", _queue.size());
                _condition.wait (lock);
-               TIMING (_("decoder wakes with queue of %1"), _queue.size());
+               TIMING ("decoder wakes with queue of %1", _queue.size());
        }
 
        if (_terminate) {
@@ -268,12 +268,12 @@ Encoder::process_video (shared_ptr<Image> image, bool same, boost::shared_ptr<Su
        } else {
                /* Queue this new frame for encoding */
                pair<string, string> const s = Filter::ffmpeg_strings (_film->filters());
-               TIMING (_("adding to queue of %1"), _queue.size ());
+               TIMING ("adding to queue of %1", _queue.size ());
                _queue.push_back (boost::shared_ptr<DCPVideoFrame> (
                                          new DCPVideoFrame (
                                                  image, sub, _film->format()->dcp_size(), _film->format()->dcp_padding (_film),
                                                  _film->subtitle_offset(), _film->subtitle_scale(),
-                                                 _film->scaler(), _video_frames_out, _film->frames_per_second(), s.second,
+                                                 _film->scaler(), _video_frames_out, _film->dcp_frame_rate(), s.second,
                                                  _film->colour_lut(), _film->j2k_bandwidth(),
                                                  _film->log()
                                                  )
@@ -286,7 +286,7 @@ Encoder::process_video (shared_ptr<Image> image, bool same, boost::shared_ptr<Su
        ++_video_frames_in;
        ++_video_frames_out;
 
-       if (dfr.repeat) {
+       if (frc.repeat) {
                _writer->repeat (_video_frames_out);
                ++_video_frames_out;
                frame_done ();
@@ -349,7 +349,7 @@ Encoder::encoder_thread (ServerDescription* server)
        
        while (1) {
 
-               TIMING (N_("encoder thread %1 sleeps"), boost::this_thread::get_id());
+               TIMING ("encoder thread %1 sleeps", boost::this_thread::get_id());
                boost::mutex::scoped_lock lock (_mutex);
                while (_queue.empty () && !_terminate) {
                        _condition.wait (lock);
@@ -359,7 +359,7 @@ Encoder::encoder_thread (ServerDescription* server)
                        return;
                }
 
-               TIMING (N_("encoder thread %1 wakes with queue of %2"), boost::this_thread::get_id(), _queue.size());
+               TIMING ("encoder thread %1 wakes with queue of %2", boost::this_thread::get_id(), _queue.size());
                boost::shared_ptr<DCPVideoFrame> vf = _queue.front ();
                _film->log()->log (String::compose (N_("Encoder thread %1 pops frame %2 from queue"), boost::this_thread::get_id(), vf->frame()), Log::VERBOSE);
                _queue.pop_front ();
@@ -393,9 +393,9 @@ Encoder::encoder_thread (ServerDescription* server)
                                
                } else {
                        try {
-                               TIMING (N_("encoder thread %1 begins local encode of %2"), boost::this_thread::get_id(), vf->frame());
+                               TIMING ("encoder thread %1 begins local encode of %2", boost::this_thread::get_id(), vf->frame());
                                encoded = vf->encode_locally ();
-                               TIMING (N_("encoder thread %1 finishes local encode of %2"), boost::this_thread::get_id(), vf->frame());
+                               TIMING ("encoder thread %1 finishes local encode of %2", boost::this_thread::get_id(), vf->frame());
                        } catch (std::exception& e) {
                                _film->log()->log (String::compose (N_("Local encode failed (%1)"), e.what ()));
                        }
@@ -425,18 +425,20 @@ Encoder::encoder_thread (ServerDescription* server)
 void
 Encoder::write_audio (shared_ptr<const AudioBuffers> data)
 {
-       if (_film->audio_channels() == 1) {
-               /* We need to switch things around so that the mono channel is on
-                  the centre channel of a 5.1 set (with other channels silent).
-               */
-
-               shared_ptr<AudioBuffers> b (new AudioBuffers (6, data->frames ()));
-               b->make_silent (libdcp::LEFT);
-               b->make_silent (libdcp::RIGHT);
-               memcpy (b->data()[libdcp::CENTRE], data->data()[0], data->frames() * sizeof(float));
-               b->make_silent (libdcp::LFE);
-               b->make_silent (libdcp::LS);
-               b->make_silent (libdcp::RS);
+       AudioMapping m (_film->audio_channels ());
+       if (m.dcp_channels() != _film->audio_channels()) {
+
+               /* Remap (currently just for mono -> 5.1) */
+
+               shared_ptr<AudioBuffers> b (new AudioBuffers (m.dcp_channels(), data->frames ()));
+               for (int i = 0; i < m.dcp_channels(); ++i) {
+                       optional<int> s = m.dcp_to_source (static_cast<libdcp::Channel> (i));
+                       if (!s) {
+                               b->make_silent (i);
+                       } else {
+                               memcpy (b->data()[i], data->data()[s.get()], data->frames() * sizeof(float));
+                       }
+               }
 
                data = b;
        }