summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2021-04-29 23:53:12 +0200
committerCarl Hetherington <cth@carlh.net>2021-05-07 09:29:59 +0200
commite4fa972e2a85affc1526abf55100111b5f540c67 (patch)
tree7ee131402529f142bc5182c3893c64de4bfaff5e /src/lib
parent9900ce33c6026e9513d9a4f2a67e4366601c1292 (diff)
Move Resampler into Piece.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/audio_decoder.cc45
-rw-r--r--src/lib/audio_decoder.h10
-rw-r--r--src/lib/dcp_content.cc4
-rw-r--r--src/lib/dcp_decoder.cc4
-rw-r--r--src/lib/dcp_decoder.h1
-rw-r--r--src/lib/decoder.h4
-rw-r--r--src/lib/decoder_factory.cc6
-rw-r--r--src/lib/decoder_factory.h1
-rw-r--r--src/lib/ffmpeg_decoder.cc6
-rw-r--r--src/lib/ffmpeg_decoder.h2
-rw-r--r--src/lib/piece.cc75
-rw-r--r--src/lib/piece.h10
-rw-r--r--src/lib/player.cc6
13 files changed, 100 insertions, 74 deletions
diff --git a/src/lib/audio_decoder.cc b/src/lib/audio_decoder.cc
index 9227cb962..643fc8be4 100644
--- a/src/lib/audio_decoder.cc
+++ b/src/lib/audio_decoder.cc
@@ -40,10 +40,9 @@ using boost::optional;
using namespace dcpomatic;
-AudioDecoder::AudioDecoder (Decoder* parent, shared_ptr<const AudioContent> content, bool fast)
+AudioDecoder::AudioDecoder (Decoder* parent, shared_ptr<const AudioContent> content)
: DecoderPart (parent)
, _content (content)
- , _fast (fast)
{
/* Set up _positions so that we have one for each stream */
for (auto i: content->streams ()) {
@@ -99,35 +98,6 @@ AudioDecoder::emit (shared_ptr<const Film> film, AudioStreamPtr stream, shared_p
_positions[stream] = time.frames_round (resampled_rate);
}
- shared_ptr<Resampler> resampler;
- auto i = _resamplers.find(stream);
- if (i != _resamplers.end()) {
- resampler = i->second;
- } else {
- if (stream->frame_rate() != resampled_rate) {
- LOG_GENERAL (
- "Creating new resampler from %1 to %2 with %3 channels",
- stream->frame_rate(),
- resampled_rate,
- stream->channels()
- );
-
- resampler = make_shared<Resampler>(stream->frame_rate(), resampled_rate, stream->channels());
- if (_fast) {
- resampler->set_fast ();
- }
- _resamplers[stream] = resampler;
- }
- }
-
- if (resampler) {
- auto ro = resampler->run (data);
- if (ro->frames() == 0) {
- return;
- }
- data = ro;
- }
-
Data(stream, data, _positions[stream]);
_positions[stream] += data->frames();
}
@@ -161,11 +131,6 @@ AudioDecoder::position (shared_ptr<const Film> film) const
void
AudioDecoder::seek ()
{
- for (auto i: _resamplers) {
- i.second->flush ();
- i.second->reset ();
- }
-
for (auto& i: _positions) {
i.second = 0;
}
@@ -175,14 +140,6 @@ AudioDecoder::seek ()
void
AudioDecoder::flush ()
{
- for (auto const& i: _resamplers) {
- auto ro = i.second->flush ();
- if (ro->frames() > 0) {
- Data (i.first, ro, _positions[i.first]);
- _positions[i.first] += ro->frames();
- }
- }
-
if (_content->delay() < 0) {
/* Finish off with the gap caused by the delay */
silence (-_content->delay ());
diff --git a/src/lib/audio_decoder.h b/src/lib/audio_decoder.h
index ff0db6e8f..e5698c4f5 100644
--- a/src/lib/audio_decoder.h
+++ b/src/lib/audio_decoder.h
@@ -49,7 +49,7 @@ class Resampler;
class AudioDecoder : public std::enable_shared_from_this<AudioDecoder>, public DecoderPart
{
public:
- AudioDecoder (Decoder* parent, std::shared_ptr<const AudioContent> content, bool fast);
+ AudioDecoder (Decoder* parent, std::shared_ptr<const AudioContent> content);
boost::optional<dcpomatic::ContentTime> position (std::shared_ptr<const Film> film) const;
void emit (std::shared_ptr<const Film> film, AudioStreamPtr stream, std::shared_ptr<const AudioBuffers>, dcpomatic::ContentTime, bool time_already_delayed = false);
@@ -64,15 +64,9 @@ private:
void silence (int milliseconds);
std::shared_ptr<const AudioContent> _content;
- /** Frame after the last one that was emitted from Data (i.e. at the resampled rate, if applicable)
- * for each AudioStream.
- */
+ /** Frame after the last one that was emitted from Data for each AudioStream */
typedef std::map<AudioStreamPtr, Frame> PositionMap;
PositionMap _positions;
- typedef std::map<AudioStreamPtr, std::shared_ptr<Resampler>> ResamplerMap;
- ResamplerMap _resamplers;
-
- bool _fast;
};
diff --git a/src/lib/dcp_content.cc b/src/lib/dcp_content.cc
index 2b67860b1..ec56716f8 100644
--- a/src/lib/dcp_content.cc
+++ b/src/lib/dcp_content.cc
@@ -692,7 +692,7 @@ DCPContent::can_reference_audio (shared_ptr<const Film> film, string& why_not) c
{
shared_ptr<DCPDecoder> decoder;
try {
- decoder.reset (new DCPDecoder (film, shared_from_this(), false, film->tolerant(), shared_ptr<DCPDecoder>()));
+ decoder.reset (new DCPDecoder (film, shared_from_this(), film->tolerant(), shared_ptr<DCPDecoder>()));
} catch (dcp::ReadError &) {
/* We couldn't read the DCP, so it's probably missing */
return false;
@@ -727,7 +727,7 @@ DCPContent::can_reference_text (shared_ptr<const Film> film, TextType type, stri
{
shared_ptr<DCPDecoder> decoder;
try {
- decoder.reset (new DCPDecoder (film, shared_from_this(), false, film->tolerant(), shared_ptr<DCPDecoder>()));
+ decoder.reset (new DCPDecoder(film, shared_from_this(), film->tolerant(), shared_ptr<DCPDecoder>()));
} catch (dcp::ReadError &) {
/* We couldn't read the DCP, so it's probably missing */
return false;
diff --git a/src/lib/dcp_decoder.cc b/src/lib/dcp_decoder.cc
index f9b0d9a57..a0b983e49 100644
--- a/src/lib/dcp_decoder.cc
+++ b/src/lib/dcp_decoder.cc
@@ -64,7 +64,7 @@ using std::make_shared;
using boost::optional;
using namespace dcpomatic;
-DCPDecoder::DCPDecoder (shared_ptr<const Film> film, shared_ptr<const DCPContent> c, bool fast, bool tolerant, shared_ptr<DCPDecoder> old)
+DCPDecoder::DCPDecoder (shared_ptr<const Film> film, shared_ptr<const DCPContent> c, bool tolerant, shared_ptr<DCPDecoder> old)
: DCP (c, tolerant)
, Decoder (film)
{
@@ -73,7 +73,7 @@ DCPDecoder::DCPDecoder (shared_ptr<const Film> film, shared_ptr<const DCPContent
video = make_shared<VideoDecoder>(this, c);
}
if (c->audio) {
- audio = make_shared<AudioDecoder>(this, c->audio, fast);
+ audio = make_shared<AudioDecoder>(this, c->audio);
}
for (auto i: c->text) {
/* XXX: this time here should be the time of the first subtitle, not 0 */
diff --git a/src/lib/dcp_decoder.h b/src/lib/dcp_decoder.h
index a4dfbad4e..e4944e3bf 100644
--- a/src/lib/dcp_decoder.h
+++ b/src/lib/dcp_decoder.h
@@ -48,7 +48,6 @@ public:
DCPDecoder (
std::shared_ptr<const Film> film,
std::shared_ptr<const DCPContent>,
- bool fast,
bool tolerant,
std::shared_ptr<DCPDecoder> old
);
diff --git a/src/lib/decoder.h b/src/lib/decoder.h
index a672e8a10..00d629f81 100644
--- a/src/lib/decoder.h
+++ b/src/lib/decoder.h
@@ -33,7 +33,7 @@
#include "font_data.h"
#include "types.h"
#include "weak_film.h"
-#include <boost/utility.hpp>
+#include <boost/signals2.hpp>
class AtmosDecoder;
@@ -74,6 +74,8 @@ public:
virtual std::vector<dcpomatic::FontData> fonts () const {
return {};
}
+
+ boost::signals2::signal<void ()> Flush;
};
diff --git a/src/lib/decoder_factory.cc b/src/lib/decoder_factory.cc
index b360eabf3..3f5c1ee1c 100644
--- a/src/lib/decoder_factory.cc
+++ b/src/lib/decoder_factory.cc
@@ -45,15 +45,15 @@ using std::dynamic_pointer_cast;
* @param old_decoder A `used' decoder that has been previously made for this piece of content, or nullptr
*/
shared_ptr<Decoder>
-decoder_factory (shared_ptr<const Film> film, shared_ptr<const Content> content, bool fast, bool tolerant, shared_ptr<Decoder> old_decoder)
+decoder_factory (shared_ptr<const Film> film, shared_ptr<const Content> content, bool tolerant, shared_ptr<Decoder> old_decoder)
{
if (auto c = dynamic_pointer_cast<const FFmpegContent>(content)) {
- return make_shared<FFmpegDecoder>(film, c, fast);
+ return make_shared<FFmpegDecoder>(film, c);
}
if (auto c = dynamic_pointer_cast<const DCPContent>(content)) {
try {
- return make_shared<DCPDecoder>(film, c, fast, tolerant, dynamic_pointer_cast<DCPDecoder>(old_decoder));
+ return make_shared<DCPDecoder>(film, c, tolerant, dynamic_pointer_cast<DCPDecoder>(old_decoder));
} catch (KDMError& e) {
/* This will be found and reported to the user when the content is examined */
return {};
diff --git a/src/lib/decoder_factory.h b/src/lib/decoder_factory.h
index 46991d873..7e8c3fafe 100644
--- a/src/lib/decoder_factory.h
+++ b/src/lib/decoder_factory.h
@@ -22,7 +22,6 @@
extern std::shared_ptr<Decoder> decoder_factory (
std::shared_ptr<const Film> film,
std::shared_ptr<const Content> content,
- bool fast,
bool tolerant,
std::shared_ptr<Decoder> old_decoder
);
diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc
index 401d26f1f..432749c29 100644
--- a/src/lib/ffmpeg_decoder.cc
+++ b/src/lib/ffmpeg_decoder.cc
@@ -78,7 +78,7 @@ using dcp::Size;
using namespace dcpomatic;
-FFmpegDecoder::FFmpegDecoder (shared_ptr<const Film> film, shared_ptr<const FFmpegContent> c, bool fast)
+FFmpegDecoder::FFmpegDecoder (shared_ptr<const Film> film, shared_ptr<const FFmpegContent> c)
: FFmpeg (c)
, Decoder (film)
{
@@ -93,7 +93,7 @@ FFmpegDecoder::FFmpegDecoder (shared_ptr<const Film> film, shared_ptr<const FFmp
}
if (c->audio) {
- audio = make_shared<AudioDecoder>(this, c->audio, fast);
+ audio = make_shared<AudioDecoder>(this, c->audio);
}
if (c->only_text()) {
@@ -174,6 +174,8 @@ FFmpegDecoder::flush ()
audio->flush ();
}
+ Flush ();
+
return true;
}
diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h
index fce3fcae9..f15257f98 100644
--- a/src/lib/ffmpeg_decoder.h
+++ b/src/lib/ffmpeg_decoder.h
@@ -44,7 +44,7 @@ struct ffmpeg_pts_offset_test;
class FFmpegDecoder : public FFmpeg, public Decoder
{
public:
- FFmpegDecoder (std::shared_ptr<const Film> film, std::shared_ptr<const FFmpegContent>, bool fast);
+ FFmpegDecoder (std::shared_ptr<const Film> film, std::shared_ptr<const FFmpegContent>);
bool pass () override;
void seek (dcpomatic::ContentTime time, bool) override;
diff --git a/src/lib/piece.cc b/src/lib/piece.cc
index 521a5e56d..bf180bc84 100644
--- a/src/lib/piece.cc
+++ b/src/lib/piece.cc
@@ -29,6 +29,7 @@
#include "piece.h"
#include "piece_video.h"
#include "player_video.h"
+#include "resampler.h"
#include "video_content.h"
#include "video_decoder.h"
@@ -42,15 +43,17 @@ using boost::optional;
using namespace dcpomatic;
-Piece::Piece (weak_ptr<const Film> film, shared_ptr<Content> c, shared_ptr<Decoder> d, FrameRateChange f)
+Piece::Piece (weak_ptr<const Film> film, shared_ptr<Content> content, shared_ptr<Decoder> decoder, FrameRateChange frc, bool fast)
: _film (film)
- , _content (c)
- , _decoder (d)
- , _frc (f)
+ , _content (content)
+ , _decoder (decoder)
+ , _frc (frc)
+ , _fast (fast)
{
if (_content->audio) {
for (auto j: _content->audio->streams()) {
_stream_last_push_end[j] = _content->position();
+ _positions[j] = 0;
}
}
@@ -61,6 +64,8 @@ Piece::Piece (weak_ptr<const Film> film, shared_ptr<Content> c, shared_ptr<Decod
if (_decoder->audio) {
_decoder->audio->Data.connect (boost::bind(&Piece::audio, this, _1, _2, _3));
}
+
+ _decoder->Flush.connect (boost::bind(&Piece::flush, this));
}
@@ -74,7 +79,46 @@ Piece::video (shared_ptr<const ImageProxy> image, Frame frame, Eyes eyes, Part p
void
Piece::audio (AudioStreamPtr stream, shared_ptr<const AudioBuffers> audio, Frame frame)
{
- Audio (PieceAudio(stream, audio, frame));
+ auto film = _film.lock ();
+ DCPOMATIC_ASSERT (film);
+
+ int const resampled_rate = _content->audio->resampled_frame_rate(film);
+
+ shared_ptr<Resampler> resampler;
+ auto i = _resamplers.find(stream);
+ if (i != _resamplers.end()) {
+ resampler = i->second;
+ } else {
+ if (stream->frame_rate() != resampled_rate) {
+ LOG_GENERAL (
+ "Creating new resampler from %1 to %2 with %3 channels",
+ stream->frame_rate(),
+ resampled_rate,
+ stream->channels()
+ );
+
+ resampler = make_shared<Resampler>(stream->frame_rate(), resampled_rate, stream->channels());
+ if (_fast) {
+ resampler->set_fast ();
+ }
+ _resamplers[stream] = resampler;
+ }
+ }
+
+ if (resampler) {
+ auto ro = resampler->run (audio);
+ if (ro->frames() == 0) {
+ return;
+ }
+ audio = ro;
+ }
+
+ if (_positions[stream] == 0) {
+ _positions[stream] = frame;
+ }
+
+ Audio (PieceAudio(stream, audio, _positions[stream]));
+ _positions[stream] += audio->frames();
}
@@ -253,6 +297,15 @@ Piece::reference_dcp_audio () const
void
Piece::seek (DCPTime time, bool accurate)
{
+ for (auto i: _resamplers) {
+ i.second->flush ();
+ i.second->reset ();
+ }
+
+ for (auto& i: _positions) {
+ i.second = 0;
+ }
+
if (time < position()) {
/* Before; seek to the start of the content. Even if this request is for an inaccurate seek
we must seek this (following) content accurately, otherwise when we come to the end of the current
@@ -316,3 +369,15 @@ Piece::period () const
return DCPTimePeriod(position(), end());
}
+
+void
+Piece::flush ()
+{
+ for (auto const& i: _resamplers) {
+ auto ro = i.second->flush ();
+ if (ro->frames() > 0) {
+ Audio (PieceAudio(i.first, ro, _positions[i.first]));
+ _positions[i.first] += ro->frames();
+ }
+ }
+}
diff --git a/src/lib/piece.h b/src/lib/piece.h
index 25d97a466..66603f797 100644
--- a/src/lib/piece.h
+++ b/src/lib/piece.h
@@ -37,6 +37,7 @@
class Content;
class Decoder;
class PlayerVideo;
+class Resampler;
struct overlap_video_test1;
struct check_reuse_old_data_test;
@@ -44,7 +45,7 @@ struct check_reuse_old_data_test;
class Piece
{
public:
- Piece (std::weak_ptr<const Film> film, std::shared_ptr<Content> c, std::shared_ptr<Decoder> d, FrameRateChange f);
+ Piece (std::weak_ptr<const Film> film, std::shared_ptr<Content> content, std::shared_ptr<Decoder> decoder, FrameRateChange frc, bool fast);
void update_pull_to (dcpomatic::DCPTime& pull_to) const;
void set_last_push_end (AudioStreamPtr stream, dcpomatic::DCPTime last_push_end);
@@ -95,13 +96,20 @@ private:
void video (std::shared_ptr<const ImageProxy> image, Frame frame, Eyes eyes, Part part);
void audio (std::shared_ptr<AudioStream> stream, std::shared_ptr<const AudioBuffers> audio, Frame frame);
+ void flush ();
+
std::weak_ptr<const Film> _film;
std::shared_ptr<Content> _content;
std::shared_ptr<Decoder> _decoder;
FrameRateChange _frc;
+ bool _fast = false;
bool _done = false;
boost::optional<dcpomatic::DCPTimePeriod> _ignore_video;
std::map<AudioStreamPtr, dcpomatic::DCPTime> _stream_last_push_end;
+
+ std::map<AudioStreamPtr, std::shared_ptr<Resampler>> _resamplers;
+ std::map<AudioStreamPtr, Frame> _positions;
+
};
diff --git a/src/lib/player.cc b/src/lib/player.cc
index 94ccc48ad..f14f4d067 100644
--- a/src/lib/player.cc
+++ b/src/lib/player.cc
@@ -186,7 +186,7 @@ Player::setup_pieces_unlocked ()
}
}
- auto decoder = decoder_factory (_film, i, _fast, _tolerant, old_decoder);
+ auto decoder = decoder_factory (_film, i, _tolerant, old_decoder);
DCPOMATIC_ASSERT (decoder);
FrameRateChange frc (_film, i);
@@ -213,7 +213,7 @@ Player::setup_pieces_unlocked ()
}
}
- auto piece = make_shared<Piece>(_film, i, decoder, frc);
+ auto piece = make_shared<Piece>(_film, i, decoder, frc, _fast);
_pieces.push_back (piece);
if (i->video) {
@@ -507,7 +507,7 @@ Player::get_reel_assets ()
unique_ptr<DCPDecoder> decoder;
try {
- decoder.reset (new DCPDecoder(_film, j, false, false, shared_ptr<DCPDecoder>()));
+ decoder.reset (new DCPDecoder(_film, j, false, shared_ptr<DCPDecoder>()));
} catch (...) {
return a;
}