#include "content_subtitle.h"
#include "dcp_decoder.h"
#include "image_decoder.h"
-#include "resampler.h"
#include "compose.hpp"
#include <dcp/reel.h>
#include <dcp/reel_sound_asset.h>
BOOST_FOREACH (shared_ptr<Piece> i, _pieces) {
if (!i->done) {
- DCPTime const t = i->content->position() + DCPTime (i->decoder->position(), i->frc);
+ DCPTime const t = content_time_to_dcp (i, i->decoder->position());
if (!earliest || t < earliest_content) {
earliest_content = t;
earliest = i;
audio_fill_from = _last_audio_time;
}
- if (audio_fill_from && audio_fill_from < fill_towards) {
- DCPTimePeriod period (*audio_fill_from, fill_towards);
+ DCPTime audio_fill_towards = fill_towards;
+ if (earliest && earliest->content->audio) {
+ audio_fill_towards += DCPTime::from_seconds (earliest->content->audio->delay() / 1000.0);
+ }
+
+ if (audio_fill_from && audio_fill_from < audio_fill_towards) {
+ DCPTimePeriod period (*audio_fill_from, audio_fill_towards);
if (period.duration() > one_video_frame()) {
period.to = period.from + one_video_frame();
}
list<DCPTimePeriod> p = subtract(period, _no_audio);
if (!p.empty ()) {
fill_audio (p.front());
+ filled = true;
}
- filled = true;
}
if (earliest) {
earliest->done = earliest->decoder->pass ();
- if (earliest->done && earliest->content->audio) {
- /* Flush the Player audio system for this piece */
- BOOST_FOREACH (AudioStreamPtr i, earliest->content->audio->streams()) {
- audio_flush (earliest, i);
- }
- }
}
/* Emit any audio that is ready */
emit_video (_last_video[wp], time);
}
-void
-Player::audio_flush (shared_ptr<Piece> piece, AudioStreamPtr stream)
-{
- shared_ptr<AudioContent> content = piece->content->audio;
- DCPOMATIC_ASSERT (content);
-
- shared_ptr<Resampler> r = resampler (content, stream, false);
- if (!r) {
- return;
- }
-
- pair<shared_ptr<const AudioBuffers>, Frame> ro = r->flush ();
- if (ro.first->frames() == 0) {
- return;
- }
-
- ContentAudio content_audio;
- content_audio.audio = ro.first;
- content_audio.frame = ro.second;
-
- /* Compute time in the DCP */
- DCPTime time = resampled_audio_to_dcp (piece, content_audio.frame) + DCPTime::from_seconds (content->delay() / 1000.0);
-
- audio_transform (content, stream, content_audio, time);
-}
-
/** Do our common processing on some audio */
void
Player::audio_transform (shared_ptr<AudioContent> content, AudioStreamPtr stream, ContentAudio content_audio, DCPTime time)
/* Remap */
- shared_ptr<AudioBuffers> dcp_mapped (new AudioBuffers (_film->audio_channels(), content_audio.audio->frames()));
- dcp_mapped->make_silent ();
-
- AudioMapping map = stream->mapping ();
- for (int i = 0; i < map.input_channels(); ++i) {
- for (int j = 0; j < dcp_mapped->channels(); ++j) {
- if (map.get (i, static_cast<dcp::Channel> (j)) > 0) {
- dcp_mapped->accumulate_channel (
- content_audio.audio.get(),
- i,
- static_cast<dcp::Channel> (j),
- map.get (i, static_cast<dcp::Channel> (j))
- );
- }
- }
- }
-
- content_audio.audio = dcp_mapped;
+ content_audio.audio = remap (content_audio.audio, _film->audio_channels(), stream->mapping());
/* Process */
content_audio.audio = _audio_processor->run (content_audio.audio, _film->audio_channels ());
}
- /* Pad any gap which may be caused by audio delay */
-
- if (_last_audio_time) {
- fill_audio (DCPTimePeriod (*_last_audio_time, time));
- }
-
/* Push */
_audio_merger.push (content_audio.audio, time);
shared_ptr<AudioContent> content = piece->content->audio;
DCPOMATIC_ASSERT (content);
- /* Resample */
- if (stream->frame_rate() != content->resampled_frame_rate()) {
- shared_ptr<Resampler> r = resampler (content, stream, true);
- pair<shared_ptr<const AudioBuffers>, Frame> ro = r->run (content_audio.audio, content_audio.frame);
- if (ro.first->frames() == 0) {
- return;
- }
- content_audio.audio = ro.first;
- content_audio.frame = ro.second;
- }
-
/* Compute time in the DCP */
DCPTime time = resampled_audio_to_dcp (piece, content_audio.frame) + DCPTime::from_seconds (content->delay() / 1000.0);
/* And the end of this block in the DCP */
_audio_processor->flush ();
}
- for (ResamplerMap::iterator i = _resamplers.begin(); i != _resamplers.end(); ++i) {
- i->second->flush ();
- i->second->reset ();
- }
-
_audio_merger.clear ();
_active_subtitles.clear ();
}
}
-shared_ptr<Resampler>
-Player::resampler (shared_ptr<const AudioContent> content, AudioStreamPtr stream, bool create)
-{
- ResamplerMap::const_iterator i = _resamplers.find (make_pair (content, stream));
- if (i != _resamplers.end ()) {
- return i->second;
- }
-
- if (!create) {
- return shared_ptr<Resampler> ();
- }
-
- LOG_GENERAL (
- "Creating new resampler from %1 to %2 with %3 channels",
- stream->frame_rate(),
- content->resampled_frame_rate(),
- stream->channels()
- );
-
- shared_ptr<Resampler> r (
- new Resampler (stream->frame_rate(), content->resampled_frame_rate(), stream->channels())
- );
-
- _resamplers[make_pair(content, stream)] = r;
- return r;
-}
-
void
Player::emit_video (shared_ptr<PlayerVideo> pv, DCPTime time)
{
return;
}
+ DCPOMATIC_ASSERT (period.from < period.to);
+
BOOST_FOREACH (DCPTimePeriod i, subtract(period, _no_audio)) {
DCPTime t = i.from;
while (t < i.to) {