From: Carl Hetherington Date: Thu, 25 Jul 2013 12:26:40 +0000 (+0100) Subject: Move resampling back into AudioDecoder and fix various screw-ups with audio in the... X-Git-Tag: v2.0.48~1337^2~132 X-Git-Url: https://git.carlh.net/gitweb/?p=dcpomatic.git;a=commitdiff_plain;h=d9362bdd24f01e4c833e89d63ac3816f36eae36e Move resampling back into AudioDecoder and fix various screw-ups with audio in the player. --- 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 f) - : Decoder (f) +AudioDecoder::AudioDecoder (shared_ptr film, shared_ptr 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 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); + AudioDecoder (boost::shared_ptr, boost::shared_ptr); /** Emitted when some audio data is ready */ boost::signals2::signal, AudioContent::Frame)> Audio; @@ -44,7 +45,9 @@ public: protected: void audio (boost::shared_ptr, AudioContent::Frame); + /** Frame index of next emission (post resampling) */ AudioContent::Frame _audio_position; + boost::shared_ptr _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 f, shared_ptr 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 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 ac = dynamic_pointer_cast (earliest->content); - assert (ac); - shared_ptr re = resampler (ac, false); - if (re) { - shared_ptr b = re->flush (); - if (b->frames ()) { - process_audio (earliest, b, ac->audio_length ()); - } - } - } } break; } @@ -277,12 +264,6 @@ Player::process_audio (weak_ptr weak_piece, shared_ptr content = dynamic_pointer_cast (piece->content); assert (content); - /* Resample */ - if (content->content_audio_frame_rate() != content->output_audio_frame_rate()) { - shared_ptr r = resampler (content, true); - audio = r->run (audio); - } - /* Remap channels */ shared_ptr dcp_mapped (new AudioBuffers (_film->audio_channels(), audio->frames())); dcp_mapped->make_silent (); @@ -295,10 +276,9 @@ Player::process_audio (weak_ptr weak_piece, shared_ptrstart() + (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 weak_piece, shared_ptr _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 weak_piece, shared_ptr 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 -Player::resampler (shared_ptr c, bool create) -{ - map, shared_ptr >::iterator i = _resamplers.find (c); - if (i != _resamplers.end ()) { - return i->second; - } - - if (!create) { - return shared_ptr (); - } - - shared_ptr 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 (boost::shared_ptr, bool); void film_changed (Film::Property); void update_subtitle (); @@ -113,8 +111,6 @@ private: libdcp::Size _video_container_size; boost::shared_ptr _black_frame; - std::map, boost::shared_ptr > _resamplers; - boost::shared_ptr _last_resampler; struct { boost::weak_ptr 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 f, shared_ptr c) : Decoder (f) - , AudioDecoder (f) + , AudioDecoder (f, c) , _sndfile_content (c) , _deinterleave_buffer (0) {