diff options
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/audio_decoder.cc | 50 | ||||
| -rw-r--r-- | src/lib/audio_decoder.h | 4 | ||||
| -rw-r--r-- | src/lib/ffmpeg_decoder.cc | 1 | ||||
| -rw-r--r-- | src/lib/player.cc | 77 | ||||
| -rw-r--r-- | src/lib/player.h | 5 | ||||
| -rw-r--r-- | src/lib/resampler.cc | 25 | ||||
| -rw-r--r-- | src/lib/resampler.h | 6 |
7 files changed, 62 insertions, 106 deletions
diff --git a/src/lib/audio_decoder.cc b/src/lib/audio_decoder.cc index 3e4584a3f..4b77a8afb 100644 --- a/src/lib/audio_decoder.cc +++ b/src/lib/audio_decoder.cc @@ -22,19 +22,24 @@ #include "audio_buffers.h" #include "audio_content.h" #include "log.h" +#include "resampler.h" #include "compose.hpp" #include <boost/foreach.hpp> #include <iostream> #include "i18n.h" +#define LOG_GENERAL(...) _log->log (String::compose (__VA_ARGS__), LogEntry::TYPE_GENERAL); + using std::cout; using std::map; +using std::pair; using boost::shared_ptr; using boost::optional; AudioDecoder::AudioDecoder (Decoder* parent, shared_ptr<const AudioContent> content, shared_ptr<Log> log) : DecoderPart (parent, log) + , _content (content) { /* Set up _positions so that we have one for each stream */ BOOST_FOREACH (AudioStreamPtr i, content->streams ()) { @@ -58,6 +63,32 @@ AudioDecoder::emit (AudioStreamPtr stream, shared_ptr<const AudioBuffers> data, _positions[stream] = time.frames_round (stream->frame_rate ()); } + shared_ptr<Resampler> resampler; + map<AudioStreamPtr, shared_ptr<Resampler> >::iterator i = _resamplers.find(stream); + if (i != _resamplers.end ()) { + resampler = i->second; + } else { + if (stream->frame_rate() != _content->resampled_frame_rate()) { + LOG_GENERAL ( + "Creating new resampler from %1 to %2 with %3 channels", + stream->frame_rate(), + _content->resampled_frame_rate(), + stream->channels() + ); + + resampler.reset (new Resampler (stream->frame_rate(), _content->resampled_frame_rate(), stream->channels())); + _resamplers[stream] = resampler; + } + } + + if (resampler) { + shared_ptr<const AudioBuffers> ro = resampler->run (data); + if (ro->frames() == 0) { + return; + } + data = ro; + } + Data (stream, ContentAudio (data, _positions[stream])); _positions[stream] += data->frames(); } @@ -67,7 +98,7 @@ AudioDecoder::position () const { optional<ContentTime> p; for (map<AudioStreamPtr, Frame>::const_iterator i = _positions.begin(); i != _positions.end(); ++i) { - ContentTime const ct = ContentTime::from_frames (i->second, i->first->frame_rate ()); + ContentTime const ct = ContentTime::from_frames (i->second, _content->resampled_frame_rate()); if (!p || ct < *p) { p = ct; } @@ -79,7 +110,24 @@ AudioDecoder::position () const void AudioDecoder::seek () { + for (map<AudioStreamPtr, shared_ptr<Resampler> >::iterator i = _resamplers.begin(); i != _resamplers.end(); ++i) { + i->second->flush (); + i->second->reset (); + } + for (map<AudioStreamPtr, Frame>::iterator i = _positions.begin(); i != _positions.end(); ++i) { i->second = 0; } } + +void +AudioDecoder::flush () +{ + for (map<AudioStreamPtr, shared_ptr<Resampler> >::iterator i = _resamplers.begin(); i != _resamplers.end(); ++i) { + shared_ptr<const AudioBuffers> ro = i->second->flush (); + if (ro->frames() > 0) { + Data (i->first, ContentAudio (ro, _positions[i->first])); + _positions[i->first] += ro->frames(); + } + } +} diff --git a/src/lib/audio_decoder.h b/src/lib/audio_decoder.h index c104d8201..fcbd8267b 100644 --- a/src/lib/audio_decoder.h +++ b/src/lib/audio_decoder.h @@ -36,6 +36,7 @@ class AudioBuffers; class AudioContent; class AudioDecoderStream; class Log; +class Resampler; /** @class AudioDecoder. * @brief Parent class for audio decoders. @@ -48,12 +49,15 @@ public: ContentTime position () const; void emit (AudioStreamPtr stream, boost::shared_ptr<const AudioBuffers>, ContentTime); void seek (); + void flush (); boost::signals2::signal<void (AudioStreamPtr, ContentAudio)> Data; private: + boost::shared_ptr<const AudioContent> _content; /** Frame after the last one that was emitted from Data for each AudioStream */ std::map<AudioStreamPtr, Frame> _positions; + std::map<AudioStreamPtr, boost::shared_ptr<Resampler> > _resamplers; }; #endif diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 1c886284b..baec57f3d 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -113,6 +113,7 @@ FFmpegDecoder::flush () if (audio) { decode_audio_packet (); + audio->flush (); } } diff --git a/src/lib/player.cc b/src/lib/player.cc index d51c94400..7f8b06458 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -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> @@ -580,12 +579,6 @@ 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); - } - } } /* Emit any audio that is ready */ @@ -709,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) @@ -802,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 */ @@ -937,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 (); @@ -969,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) { @@ -1026,6 +950,7 @@ Player::fill_audio (DCPTimePeriod period) 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) { diff --git a/src/lib/player.h b/src/lib/player.h index 20c55e26d..20d9c9388 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -45,7 +45,6 @@ class Playlist; class Font; class AudioBuffers; class ReferencedReelAsset; -class Resampler; /** @class Player * @brief A class which can `play' a Playlist. @@ -107,10 +106,8 @@ private: void image_subtitle_start (boost::weak_ptr<Piece>, ContentImageSubtitle); void text_subtitle_start (boost::weak_ptr<Piece>, ContentTextSubtitle); void subtitle_stop (boost::weak_ptr<Piece>, ContentTime); - boost::shared_ptr<Resampler> resampler (boost::shared_ptr<const AudioContent> content, AudioStreamPtr stream, bool create); DCPTime one_video_frame () const; void fill_audio (DCPTimePeriod period); - void audio_flush (boost::shared_ptr<Piece>, AudioStreamPtr stream); void audio_transform (boost::shared_ptr<AudioContent> content, AudioStreamPtr stream, ContentAudio content_audio, DCPTime time); std::pair<boost::shared_ptr<AudioBuffers>, DCPTime> discard_audio ( boost::shared_ptr<const AudioBuffers> audio, DCPTime time, DCPTime discard_to @@ -173,8 +170,6 @@ private: ActiveSubtitles _active_subtitles; boost::shared_ptr<AudioProcessor> _audio_processor; - typedef std::map<std::pair<boost::shared_ptr<const AudioContent>, AudioStreamPtr>, boost::shared_ptr<Resampler> > ResamplerMap; - ResamplerMap _resamplers; boost::signals2::scoped_connection _film_changed_connection; boost::signals2::scoped_connection _playlist_changed_connection; diff --git a/src/lib/resampler.cc b/src/lib/resampler.cc index e991591c2..553180f08 100644 --- a/src/lib/resampler.cc +++ b/src/lib/resampler.cc @@ -67,19 +67,9 @@ Resampler::set_fast () } } -pair<shared_ptr<const AudioBuffers>, Frame> -Resampler::run (shared_ptr<const AudioBuffers> in, Frame frame) +shared_ptr<const AudioBuffers> +Resampler::run (shared_ptr<const AudioBuffers> in) { - if (!_next_in || !_next_out || _next_in.get() != frame) { - /* Either there was a discontinuity in the input or this is the first input; - reset _next_out. - */ - _next_out = lrintf (frame * _out_rate / _in_rate); - } - - /* Expected next input frame */ - _next_in = frame + in->frames (); - int in_frames = in->frames (); int in_offset = 0; int out_offset = 0; @@ -154,15 +144,10 @@ Resampler::run (shared_ptr<const AudioBuffers> in, Frame frame) delete[] data.data_out; } - Frame out_frame = _next_out.get (); - - /* Expected next output frame */ - _next_out = _next_out.get() + resampled->frames(); - - return make_pair (resampled, out_frame); + return resampled; } -pair<shared_ptr<const AudioBuffers>, Frame> +shared_ptr<const AudioBuffers> Resampler::flush () { shared_ptr<AudioBuffers> out (new AudioBuffers (_channels, 0)); @@ -200,7 +185,7 @@ Resampler::flush () out->set_frames (out_offset); delete[] buffer; - return make_pair (out, _next_out.get ()); + return out; } void diff --git a/src/lib/resampler.h b/src/lib/resampler.h index 9e9304fb4..4b19dc511 100644 --- a/src/lib/resampler.h +++ b/src/lib/resampler.h @@ -31,8 +31,8 @@ public: Resampler (int, int, int); ~Resampler (); - std::pair<boost::shared_ptr<const AudioBuffers>, Frame> run (boost::shared_ptr<const AudioBuffers>, Frame); - std::pair<boost::shared_ptr<const AudioBuffers>, Frame> flush (); + boost::shared_ptr<const AudioBuffers> run (boost::shared_ptr<const AudioBuffers>); + boost::shared_ptr<const AudioBuffers> flush (); void reset (); void set_fast (); @@ -41,6 +41,4 @@ private: int _in_rate; int _out_rate; int _channels; - boost::optional<Frame> _next_in; - boost::optional<Frame> _next_out; }; |
