Hopefully much cleaner handling of PTS changes under resample.
[dcpomatic.git] / src / lib / player.cc
index 1ab164d867f216f80c44bb0dd8c4e5c24fd9b0ad..620efbd0dc30cb17bcde648f75dadfbf71fae5c1 100644 (file)
@@ -31,6 +31,7 @@
 #include "job.h"
 #include "image.h"
 #include "ratio.h"
+#include "resampler.h"
 #include "log.h"
 #include "scaler.h"
 
@@ -190,6 +191,19 @@ Player::pass ()
                        cout << "Pass " << *earliest << "\n";
 #endif                 
                        earliest->decoder->pass ();
+
+                       if (earliest->decoder->done()) {
+                               shared_ptr<AudioContent> ac = dynamic_pointer_cast<AudioContent> (earliest->content);
+                               assert (ac);
+                               shared_ptr<Resampler> re = resampler (ac, false);
+                               if (re) {
+                                       shared_ptr<const AudioBuffers> b = re->flush ();
+                                       if (b->frames ()) {
+                                               process_audio (earliest, b, ac->audio_length ());
+                                       }
+                               }
+                       }
+       
                }
                break;
        }
@@ -264,6 +278,14 @@ Player::process_audio (weak_ptr<Piece> weak_piece, shared_ptr<const AudioBuffers
        shared_ptr<AudioContent> content = dynamic_pointer_cast<AudioContent> (piece->content);
        assert (content);
 
+       /* Resample */
+       if (content->content_audio_frame_rate() != content->output_audio_frame_rate()) {
+               shared_ptr<Resampler> r = resampler (content, true);
+               pair<shared_ptr<const AudioBuffers>, AudioContent::Frame> ro = r->run (audio, frame);
+               audio = ro.first;
+               frame = ro.second;
+       }
+       
        /* Remap channels */
        shared_ptr<AudioBuffers> dcp_mapped (new AudioBuffers (_film->audio_channels(), audio->frames()));
        dcp_mapped->make_silent ();
@@ -314,6 +336,7 @@ Player::process_audio (weak_ptr<Piece> weak_piece, shared_ptr<const AudioBuffers
                shared_ptr<AudioBuffers> emit (new AudioBuffers (_audio_buffers.channels(), N));
                emit->copy_from (&_audio_buffers, N, 0, 0);
                Audio (emit, _audio_position);
+
                _audio_position = piece->audio_position = _audio_position + _film->audio_frames_to_time (N);
 
                /* And remove it from our buffers */
@@ -497,6 +520,23 @@ Player::set_video_container_size (libdcp::Size s)
        _black_frame->make_black ();
 }
 
+shared_ptr<Resampler>
+Player::resampler (shared_ptr<AudioContent> c, bool create)
+{
+       map<shared_ptr<AudioContent>, shared_ptr<Resampler> >::iterator i = _resamplers.find (c);
+       if (i != _resamplers.end ()) {
+               return i->second;
+       }
+
+       if (!create) {
+               return shared_ptr<Resampler> ();
+       }
+       
+       shared_ptr<Resampler> r (new Resampler (c->content_audio_frame_rate(), c->output_audio_frame_rate(), c->audio_channels()));
+       _resamplers[c] = r;
+       return r;
+}
+
 void
 Player::emit_black ()
 {