BOOST_FOREACH (Buffer i, _buffers) {
if (i.period().to <= time) {
/* Completely within the pull period */
+ DCPOMATIC_ASSERT (i.audio->frames() > 0);
out.push_back (make_pair (i.audio, i.time));
} else if (i.time < time) {
/* Overlaps the end of the pull period */
shared_ptr<AudioBuffers> audio (new AudioBuffers (i.audio->channels(), frames(DCPTime(time - i.time))));
audio->copy_from (i.audio.get(), audio->frames(), 0, 0);
+ DCPOMATIC_ASSERT (audio->frames() > 0);
out.push_back (make_pair (audio, i.time));
i.audio->trim_start (audio->frames ());
i.time += DCPTime::from_frames(audio->frames(), _frame_rate);
+ DCPOMATIC_ASSERT (i.audio->frames() > 0);
new_buffers.push_back (i);
} else {
/* Not involved */
+ DCPOMATIC_ASSERT (i.audio->frames() > 0);
new_buffers.push_back (i);
}
}
_buffers = new_buffers;
+
+ for (list<pair<shared_ptr<AudioBuffers>, DCPTime> >::const_iterator i = out.begin(); i != out.end(); ++i) {
+ DCPOMATIC_ASSERT (i->first->frames() > 0);
+ }
+
return out;
}
AudioMerger::push (boost::shared_ptr<const AudioBuffers> audio, DCPTime time)
{
DCPOMATIC_ASSERT (time >= _last_pull);
+ DCPOMATIC_ASSERT (audio->frames() > 0);
DCPTimePeriod period (time, time + DCPTime::from_frames (audio->frames(), _frame_rate));
if (before == _buffers.end() && after == _buffers.end()) {
/* New buffer */
+ DCPOMATIC_ASSERT (part->frames() > 0);
_buffers.push_back (Buffer (part, time, _frame_rate));
} else if (before != _buffers.end() && after == _buffers.end()) {
/* We have an existing buffer before this one; append new data to it */
avcodec_flush_buffers (video_codec_context());
}
- /* XXX: should be flushing audio buffers? */
+ BOOST_FOREACH (shared_ptr<FFmpegAudioStream> i, ffmpeg_content()->ffmpeg_audio_streams()) {
+ avcodec_flush_buffers (i->stream(_format_context)->codec);
+ }
if (subtitle_codec_context ()) {
avcodec_flush_buffers (subtitle_codec_context ());
}
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;
void
Player::audio_transform (shared_ptr<AudioContent> content, AudioStreamPtr stream, ContentAudio content_audio, DCPTime time)
{
+ DCPOMATIC_ASSERT (content_audio.audio->frames() > 0);
+
/* Gain */
if (content->gain() != 0) {
void
Player::audio (weak_ptr<Piece> wp, AudioStreamPtr stream, ContentAudio content_audio)
{
+ DCPOMATIC_ASSERT (content_audio.audio->frames() > 0);
+
shared_ptr<Piece> piece = wp.lock ();
if (!piece) {
return;
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;
}
return;
} else if (end > piece->content->end()) {
Frame const remaining_frames = DCPTime(piece->content->end() - time).frames_round(_film->audio_frame_rate());
+ DCPOMATIC_ASSERT (remaining_frames > 0);
shared_ptr<AudioBuffers> cut (new AudioBuffers (content_audio.audio->channels(), remaining_frames));
cut->copy_from (content_audio.audio.get(), remaining_frames, 0, 0);
content_audio.audio = cut;
_audio_processor->flush ();
}
+ for (ResamplerMap::iterator i = _resamplers.begin(); i != _resamplers.end(); ++i) {
+ i->second->flush ();
+ i->second->reset ();
+ }
+
BOOST_FOREACH (shared_ptr<Piece> i, _pieces) {
+ i->done = false;
if (i->content->position() <= time && time < i->content->end()) {
i->decoder->seek (dcp_to_content_time (i, time), accurate);
- i->done = false;
}
}
delete[] buffer;
return make_pair (out, _next_out.get ());
}
+
+void
+Resampler::reset ()
+{
+ src_reset (_src);
+}
std::pair<boost::shared_ptr<const AudioBuffers>, Frame> run (boost::shared_ptr<const AudioBuffers>, Frame);
std::pair<boost::shared_ptr<const AudioBuffers>, Frame> flush ();
+ void reset ();
void set_fast ();
private:
return;
}
+ bool const was_running = stop ();
+
_butler->seek (t, accurate);
_last_seek_accurate = accurate;
get ();
+
+ if (was_running) {
+ start ();
+ }
}
void