summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2017-05-13 20:50:07 +0100
committerCarl Hetherington <cth@carlh.net>2017-05-13 20:50:07 +0100
commitb37249ba5db6bd08fdfe340cec923130ee4cc7b9 (patch)
tree68bb3a34adde64b5ead32186e27bd1295d57bb45 /src
parent0c11ef36be9864ec795f68410c862d70c8320bc0 (diff)
Fill audio in the Player.
Diffstat (limited to 'src')
-rw-r--r--src/lib/player.cc48
-rw-r--r--src/lib/player.h1
-rw-r--r--src/lib/playlist.cc12
-rw-r--r--src/lib/playlist.h1
4 files changed, 53 insertions, 9 deletions
diff --git a/src/lib/player.cc b/src/lib/player.cc
index a186202db..d9f03b7a4 100644
--- a/src/lib/player.cc
+++ b/src/lib/player.cc
@@ -538,26 +538,50 @@ Player::pass ()
}
}
+ /* Fill towards the next thing that might happen (or the end of the playlist). This is to fill gaps between content,
+ NOT to fill gaps within content (the latter is done in ::video())
+ */
DCPTime fill_towards = earliest ? earliest_content : _playlist->length();
- optional<DCPTime> fill_from;
- if (_last_video_time) {
+ /* Work out where to fill video from */
+ optional<DCPTime> video_fill_from;
+ if (_last_video_time && !_playlist->video_content_at(_last_video_time.get())) {
/* No seek; fill towards the next thing that might happen (or the end of the playlist) */
- fill_from = _last_video_time;
+ video_fill_from = _last_video_time;
} else if (_last_seek_time && !_playlist->video_content_at(_last_seek_time.get())) {
/* Seek into an empty area; fill from the seek time */
- fill_from = _last_seek_time;
+ video_fill_from = _last_seek_time;
}
bool filled = false;
- if (fill_from && ((fill_towards - fill_from.get())) > one_video_frame()) {
- emit_video (black_player_video_frame(), fill_from.get());
+
+ if (video_fill_from && ((fill_towards - video_fill_from.get())) > one_video_frame()) {
+ emit_video (black_player_video_frame(), video_fill_from.get());
filled = true;
} else if (_playlist->length() == DCPTime()) {
+ /* Special case of an empty Film; just give one black frame */
emit_video (black_player_video_frame(), DCPTime());
filled = true;
}
+ optional<DCPTime> audio_fill_from;
+ if (_last_audio_time && !_playlist->audio_content_at(_last_audio_time.get())) {
+ /* No seek; fill from the last thing that happened */
+ audio_fill_from = _last_audio_time;
+ } else if (_last_seek_time && !_playlist->audio_content_at(_last_seek_time.get())) {
+ /* Seek into an empty area; fill from the seek time */
+ audio_fill_from = _last_seek_time;
+ }
+
+ if (audio_fill_from && audio_fill_from < fill_towards) {
+ DCPTimePeriod period (audio_fill_from.get(), fill_towards);
+ if (period.duration() > one_video_frame()) {
+ period.to = period.from + one_video_frame();
+ }
+ fill_audio (period);
+ filled = true;
+ }
+
if (!earliest && !filled) {
return true;
}
@@ -588,8 +612,7 @@ Player::pass ()
fill_audio (DCPTimePeriod (_last_audio_time.get(), i->second));
}
- Audio (i->first, i->second);
- _last_audio_time = i->second + DCPTime::from_frames(i->first->frames(), _film->audio_frame_rate());
+ emit_audio (i->first, i->second);
}
return false;
@@ -971,6 +994,13 @@ Player::emit_video (shared_ptr<PlayerVideo> pv, DCPTime time)
}
void
+Player::emit_audio (shared_ptr<AudioBuffers> data, DCPTime time)
+{
+ Audio (data, time);
+ _last_audio_time = time + DCPTime::from_frames (data->frames(), _film->audio_frame_rate ());
+}
+
+void
Player::fill_audio (DCPTimePeriod period)
{
BOOST_FOREACH (DCPTimePeriod i, subtract(period, _no_audio)) {
@@ -981,7 +1011,7 @@ Player::fill_audio (DCPTimePeriod period)
if (samples) {
shared_ptr<AudioBuffers> silence (new AudioBuffers (_film->audio_channels(), samples));
silence->make_silent ();
- Audio (silence, t);
+ emit_audio (silence, t);
}
t += block;
}
diff --git a/src/lib/player.h b/src/lib/player.h
index a66eb8bbb..dc942bd83 100644
--- a/src/lib/player.h
+++ b/src/lib/player.h
@@ -117,6 +117,7 @@ private:
) const;
boost::optional<PositionImage> subtitles_for_frame (DCPTime time) const;
void emit_video (boost::shared_ptr<PlayerVideo> pv, DCPTime time);
+ void emit_audio (boost::shared_ptr<AudioBuffers> data, DCPTime time);
boost::shared_ptr<const Film> _film;
boost::shared_ptr<const Playlist> _playlist;
diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc
index 09b67e921..d37f28783 100644
--- a/src/lib/playlist.cc
+++ b/src/lib/playlist.cc
@@ -555,6 +555,18 @@ Playlist::video_content_at (DCPTime time) const
return false;
}
+bool
+Playlist::audio_content_at (DCPTime time) const
+{
+ BOOST_FOREACH (shared_ptr<Content> i, _content) {
+ if (i->audio && i->position() <= time && time < i->end()) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
pair<double, double>
Playlist::speed_up_range (int dcp_video_frame_rate) const
{
diff --git a/src/lib/playlist.h b/src/lib/playlist.h
index 1ce5f247a..25dcda202 100644
--- a/src/lib/playlist.h
+++ b/src/lib/playlist.h
@@ -56,6 +56,7 @@ public:
ContentList content () const;
bool video_content_at (DCPTime time) const;
+ bool audio_content_at (DCPTime time) const;
std::string video_identifier () const;