From fa4d2529d63bcfa7cf7c516b7227e20a1b6dec7e Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 21 May 2017 19:48:14 +0100 Subject: Do resampling in AudioDecoder rather than Player. This fixes the problem where the decoder's position would not take into account that all samples pushed into the resampler do not always immediately come out. This would result in Player thinking that there would be gaps when there are not. --- src/lib/audio_decoder.cc | 50 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) (limited to 'src/lib/audio_decoder.cc') 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 #include #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 content, shared_ptr 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 data, _positions[stream] = time.frames_round (stream->frame_rate ()); } + shared_ptr resampler; + map >::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 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 p; for (map::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 >::iterator i = _resamplers.begin(); i != _resamplers.end(); ++i) { + i->second->flush (); + i->second->reset (); + } + for (map::iterator i = _positions.begin(); i != _positions.end(); ++i) { i->second = 0; } } + +void +AudioDecoder::flush () +{ + for (map >::iterator i = _resamplers.begin(); i != _resamplers.end(); ++i) { + shared_ptr ro = i->second->flush (); + if (ro->frames() > 0) { + Data (i->first, ContentAudio (ro, _positions[i->first])); + _positions[i->first] += ro->frames(); + } + } +} -- cgit v1.2.3