diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-07-25 13:26:40 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-07-25 13:26:40 +0100 |
| commit | d9362bdd24f01e4c833e89d63ac3816f36eae36e (patch) | |
| tree | e1355acbfad222fb14ec386b14dcddce0b212bb5 /src/lib | |
| parent | fd970b185e9357522f5d12d62800df8769764729 (diff) | |
Move resampling back into AudioDecoder and fix various screw-ups with audio in the player.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/audio_decoder.cc | 23 | ||||
| -rw-r--r-- | src/lib/audio_decoder.h | 5 | ||||
| -rw-r--r-- | src/lib/ffmpeg_decoder.cc | 2 | ||||
| -rw-r--r-- | src/lib/job.cc | 9 | ||||
| -rw-r--r-- | src/lib/job.h | 2 | ||||
| -rw-r--r-- | src/lib/player.cc | 49 | ||||
| -rw-r--r-- | src/lib/player.h | 4 | ||||
| -rw-r--r-- | src/lib/sndfile_decoder.cc | 2 |
8 files changed, 43 insertions, 53 deletions
diff --git a/src/lib/audio_decoder.cc b/src/lib/audio_decoder.cc index 59c631632..0ed3505cf 100644 --- a/src/lib/audio_decoder.cc +++ b/src/lib/audio_decoder.cc @@ -21,6 +21,7 @@ #include "audio_buffers.h" #include "exceptions.h" #include "log.h" +#include "resampler.h" #include "i18n.h" @@ -31,16 +32,30 @@ using std::cout; using boost::optional; using boost::shared_ptr; -AudioDecoder::AudioDecoder (shared_ptr<const Film> f) - : Decoder (f) +AudioDecoder::AudioDecoder (shared_ptr<const Film> film, shared_ptr<const AudioContent> content) + : Decoder (film) , _audio_position (0) { - + if (content->content_audio_frame_rate() != content->output_audio_frame_rate()) { + _resampler.reset ( + new Resampler ( + content->content_audio_frame_rate(), + content->output_audio_frame_rate(), + content->audio_channels() + ) + ); + } } void AudioDecoder::audio (shared_ptr<const AudioBuffers> data, AudioContent::Frame frame) { - Audio (data, frame); + /* XXX: no-one's calling _resampler->flush() again */ + + if (_resampler) { + data = _resampler->run (data); + } + + Audio (data, _audio_position); _audio_position = frame + data->frames (); } diff --git a/src/lib/audio_decoder.h b/src/lib/audio_decoder.h index 2ad53da8b..b1ec54a7b 100644 --- a/src/lib/audio_decoder.h +++ b/src/lib/audio_decoder.h @@ -29,6 +29,7 @@ #include "audio_content.h" class AudioBuffers; +class Resampler; /** @class AudioDecoder. * @brief Parent class for audio decoders. @@ -36,7 +37,7 @@ class AudioBuffers; class AudioDecoder : public virtual Decoder { public: - AudioDecoder (boost::shared_ptr<const Film>); + AudioDecoder (boost::shared_ptr<const Film>, boost::shared_ptr<const AudioContent>); /** Emitted when some audio data is ready */ boost::signals2::signal<void (boost::shared_ptr<const AudioBuffers>, AudioContent::Frame)> Audio; @@ -44,7 +45,9 @@ public: protected: void audio (boost::shared_ptr<const AudioBuffers>, AudioContent::Frame); + /** Frame index of next emission (post resampling) */ AudioContent::Frame _audio_position; + boost::shared_ptr<Resampler> _resampler; }; #endif diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 8329cad65..d8319723a 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -60,7 +60,7 @@ using libdcp::Size; FFmpegDecoder::FFmpegDecoder (shared_ptr<const Film> f, shared_ptr<const FFmpegContent> c, bool video, bool audio) : Decoder (f) , VideoDecoder (f, c) - , AudioDecoder (f) + , AudioDecoder (f, c) , SubtitleDecoder (f) , FFmpeg (c) , _subtitle_codec_context (0) diff --git a/src/lib/job.cc b/src/lib/job.cc index e63ea6dc8..12dc88fbc 100644 --- a/src/lib/job.cc +++ b/src/lib/job.cc @@ -34,6 +34,7 @@ using std::string; using std::list; +using std::cout; using std::stringstream; using boost::shared_ptr; @@ -43,6 +44,7 @@ Job::Job (shared_ptr<const Film> f) , _state (NEW) , _start_time (0) , _progress_unknown (false) + , _last_set (0) , _ran_for (0) { descend (1); @@ -213,6 +215,13 @@ Job::elapsed_time () const void Job::set_progress (float p) { + if (fabs (p - _last_set) < 0.01) { + /* Calm excessive progress reporting */ + return; + } + + _last_set = p; + boost::mutex::scoped_lock lm (_progress_mutex); _progress_unknown = false; _stack.back().normalised = p; diff --git a/src/lib/job.h b/src/lib/job.h index 343d40095..eb09ba386 100644 --- a/src/lib/job.h +++ b/src/lib/job.h @@ -126,6 +126,8 @@ private: /** true if this job's progress will always be unknown */ bool _progress_unknown; + float _last_set; + int _ran_for; }; diff --git a/src/lib/player.cc b/src/lib/player.cc index 8cc1849e8..1ab164d86 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -31,7 +31,6 @@ #include "job.h" #include "image.h" #include "ratio.h" -#include "resampler.h" #include "log.h" #include "scaler.h" @@ -191,18 +190,6 @@ 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; } @@ -277,12 +264,6 @@ 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); - audio = r->run (audio); - } - /* Remap channels */ shared_ptr<AudioBuffers> dcp_mapped (new AudioBuffers (_film->audio_channels(), audio->frames())); dcp_mapped->make_silent (); @@ -295,10 +276,9 @@ Player::process_audio (weak_ptr<Piece> weak_piece, shared_ptr<const AudioBuffers audio = dcp_mapped; - /* Convert frame to time. After resampling, the frame time (in the DCP rate) will be T_D where - T_D = frame * DCP_rate / original_rate. Hence the time in seconds is T_D / DCP_rate. - */ - Time time = content->start() + (frame * TIME_HZ / _film->audio_frame_rate()) + (content->audio_delay() * TIME_HZ / 1000); + Time time = content->start() + + _film->audio_frames_to_time (frame) + + (content->audio_delay() * TIME_HZ / 1000); /* We must cut off anything that comes before the start of all time */ if (time < 0) { @@ -319,7 +299,7 @@ Player::process_audio (weak_ptr<Piece> weak_piece, shared_ptr<const AudioBuffers */ if (time > _audio_position) { - /* We can emit some audio from our buffers */ + /* We can emit some audio from our buffers; this is how many frames */ OutputAudioFrame const N = _film->time_to_audio_frames (time - _audio_position); if (N > _audio_buffers.frames()) { /* We need some extra silence before whatever is in the buffers */ @@ -329,10 +309,12 @@ Player::process_audio (weak_ptr<Piece> weak_piece, shared_ptr<const AudioBuffers _audio_buffers.set_frames (N); } assert (N <= _audio_buffers.frames()); + + /* XXX: not convinced that a copy is necessary here */ 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 = time + _film->audio_frames_to_time (N); + _audio_position = piece->audio_position = _audio_position + _film->audio_frames_to_time (N); /* And remove it from our buffers */ if (_audio_buffers.frames() > N) { @@ -515,23 +497,6 @@ 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 () { diff --git a/src/lib/player.h b/src/lib/player.h index baaa85791..5b1b6936b 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -35,7 +35,6 @@ class Playlist; class AudioContent; class Piece; class Image; -class Resampler; /** @class Player * @brief A class which can `play' a Playlist; emitting its audio and video. @@ -90,7 +89,6 @@ private: void flush (); void emit_black (); void emit_silence (OutputAudioFrame); - boost::shared_ptr<Resampler> resampler (boost::shared_ptr<AudioContent>, bool); void film_changed (Film::Property); void update_subtitle (); @@ -113,8 +111,6 @@ private: libdcp::Size _video_container_size; boost::shared_ptr<Image> _black_frame; - std::map<boost::shared_ptr<AudioContent>, boost::shared_ptr<Resampler> > _resamplers; - boost::shared_ptr<Resampler> _last_resampler; struct { boost::weak_ptr<Piece> piece; diff --git a/src/lib/sndfile_decoder.cc b/src/lib/sndfile_decoder.cc index 1fc1ecaf2..09ccf4fbc 100644 --- a/src/lib/sndfile_decoder.cc +++ b/src/lib/sndfile_decoder.cc @@ -35,7 +35,7 @@ using boost::shared_ptr; SndfileDecoder::SndfileDecoder (shared_ptr<const Film> f, shared_ptr<const SndfileContent> c) : Decoder (f) - , AudioDecoder (f) + , AudioDecoder (f, c) , _sndfile_content (c) , _deinterleave_buffer (0) { |
