Do resampling in AudioDecoder rather than Player.
[dcpomatic.git] / src / lib / player.cc
index bd33963a0234d0cb430c1106733a9d895914a4fc..7f8b06458bd06876101e3dd6f9b51d26f4fc7bd6 100644 (file)
@@ -47,7 +47,6 @@
 #include "content_subtitle.h"
 #include "dcp_decoder.h"
 #include "image_decoder.h"
-#include "resampler.h"
 #include "compose.hpp"
 #include <dcp/reel.h>
 #include <dcp/reel_sound_asset.h>
@@ -519,7 +518,7 @@ Player::pass ()
 
        BOOST_FOREACH (shared_ptr<Piece> i, _pieces) {
                if (!i->done) {
-                       DCPTime const t = i->content->position() + DCPTime (i->decoder->position(), i->frc);
+                       DCPTime const t = content_time_to_dcp (i, i->decoder->position());
                        if (!earliest || t < earliest_content) {
                                earliest_content = t;
                                earliest = i;
@@ -527,20 +526,10 @@ Player::pass ()
                }
        }
 
-       if (earliest) {
-               earliest->done = earliest->decoder->pass ();
-               if (earliest->done && earliest->content->audio) {
-                       /* Flush the Player audio system for this piece */
-                       BOOST_FOREACH (AudioStreamPtr i, earliest->content->audio->streams()) {
-                               audio_flush (earliest, i);
-                       }
-               }
-       }
-
        /* Fill towards the next thing that might happen (or the end of the playlist).  This is to fill gaps between content,
           NOT to fill gaps within content (the latter is done in ::video())
        */
-       DCPTime fill_towards = earliest ? earliest_content : _playlist->length();
+       DCPTime fill_towards = earliest ? earliest_content : _playlist->length().ceil(_film->video_frame_rate());
 
        /* Work out where to fill video from */
        optional<DCPTime> video_fill_from;
@@ -566,22 +555,30 @@ Player::pass ()
        }
 
        optional<DCPTime> audio_fill_from;
-       if (_last_audio_time && !_playlist->audio_content_at(*_last_audio_time)) {
+       if (_last_audio_time) {
                /* Fill from the last audio or seek time */
                audio_fill_from = _last_audio_time;
        }
 
-       /* XXX: _no_audio */
-       if (audio_fill_from && audio_fill_from < fill_towards) {
-               DCPTimePeriod period (*audio_fill_from, fill_towards);
+       DCPTime audio_fill_towards = fill_towards;
+       if (earliest && earliest->content->audio) {
+               audio_fill_towards += DCPTime::from_seconds (earliest->content->audio->delay() / 1000.0);
+       }
+
+       if (audio_fill_from && audio_fill_from < audio_fill_towards) {
+               DCPTimePeriod period (*audio_fill_from, audio_fill_towards);
                if (period.duration() > one_video_frame()) {
                        period.to = period.from + one_video_frame();
                }
-               list<DCPTimePeriod> p = subtract(period, _no_video);
+               list<DCPTimePeriod> p = subtract(period, _no_audio);
                if (!p.empty ()) {
-                       fill_audio (period);
+                       fill_audio (p.front());
+                       filled = true;
                }
-               filled = true;
+       }
+
+       if (earliest) {
+               earliest->done = earliest->decoder->pass ();
        }
 
        /* Emit any audio that is ready */
@@ -705,32 +702,6 @@ Player::video (weak_ptr<Piece> wp, ContentVideo video)
        emit_video (_last_video[wp], time);
 }
 
-void
-Player::audio_flush (shared_ptr<Piece> piece, AudioStreamPtr stream)
-{
-       shared_ptr<AudioContent> content = piece->content->audio;
-       DCPOMATIC_ASSERT (content);
-
-       shared_ptr<Resampler> r = resampler (content, stream, false);
-       if (!r) {
-               return;
-       }
-
-       pair<shared_ptr<const AudioBuffers>, Frame> ro = r->flush ();
-       if (ro.first->frames() == 0) {
-               return;
-       }
-
-       ContentAudio content_audio;
-       content_audio.audio = ro.first;
-       content_audio.frame = ro.second;
-
-       /* Compute time in the DCP */
-       DCPTime time = resampled_audio_to_dcp (piece, content_audio.frame) + DCPTime::from_seconds (content->delay() / 1000.0);
-
-       audio_transform (content, stream, content_audio, time);
-}
-
 /** Do our common processing on some audio */
 void
 Player::audio_transform (shared_ptr<AudioContent> content, AudioStreamPtr stream, ContentAudio content_audio, DCPTime time)
@@ -798,17 +769,6 @@ Player::audio (weak_ptr<Piece> wp, AudioStreamPtr stream, ContentAudio content_a
        shared_ptr<AudioContent> content = piece->content->audio;
        DCPOMATIC_ASSERT (content);
 
-       /* Resample */
-       if (stream->frame_rate() != content->resampled_frame_rate()) {
-               shared_ptr<Resampler> r = resampler (content, stream, true);
-               pair<shared_ptr<const AudioBuffers>, Frame> ro = r->run (content_audio.audio, content_audio.frame);
-               if (ro.first->frames() == 0) {
-                       return;
-               }
-               content_audio.audio = ro.first;
-               content_audio.frame = ro.second;
-       }
-
        /* Compute time in the DCP */
        DCPTime time = resampled_audio_to_dcp (piece, content_audio.frame) + DCPTime::from_seconds (content->delay() / 1000.0);
        /* And the end of this block in the DCP */
@@ -933,11 +893,6 @@ Player::seek (DCPTime time, bool accurate)
                _audio_processor->flush ();
        }
 
-       for (ResamplerMap::iterator i = _resamplers.begin(); i != _resamplers.end(); ++i) {
-               i->second->flush ();
-               i->second->reset ();
-       }
-
        _audio_merger.clear ();
        _active_subtitles.clear ();
 
@@ -965,33 +920,6 @@ Player::seek (DCPTime time, bool accurate)
        }
 }
 
-shared_ptr<Resampler>
-Player::resampler (shared_ptr<const AudioContent> content, AudioStreamPtr stream, bool create)
-{
-       ResamplerMap::const_iterator i = _resamplers.find (make_pair (content, stream));
-       if (i != _resamplers.end ()) {
-               return i->second;
-       }
-
-       if (!create) {
-               return shared_ptr<Resampler> ();
-       }
-
-       LOG_GENERAL (
-               "Creating new resampler from %1 to %2 with %3 channels",
-               stream->frame_rate(),
-               content->resampled_frame_rate(),
-               stream->channels()
-               );
-
-       shared_ptr<Resampler> r (
-               new Resampler (stream->frame_rate(), content->resampled_frame_rate(), stream->channels())
-               );
-
-       _resamplers[make_pair(content, stream)] = r;
-       return r;
-}
-
 void
 Player::emit_video (shared_ptr<PlayerVideo> pv, DCPTime time)
 {
@@ -1018,6 +946,11 @@ Player::emit_audio (shared_ptr<AudioBuffers> data, DCPTime time)
 void
 Player::fill_audio (DCPTimePeriod period)
 {
+       if (period.from == period.to) {
+               return;
+       }
+
+       cout << "fillin " << to_string(period.from) << " to " << to_string(period.to) << "\n";
        BOOST_FOREACH (DCPTimePeriod i, subtract(period, _no_audio)) {
                DCPTime t = i.from;
                while (t < i.to) {