+
+FFmpegDecoder::FlushResult
+FFmpegDecoder::flush_fill()
+{
+ /* Make sure all streams are the same length and round up to the next video frame */
+
+ bool did_something = false;
+
+ auto const frc = film()->active_frame_rate_change(_ffmpeg_content->position());
+ ContentTime full_length (_ffmpeg_content->full_length(film()), frc);
+ full_length = full_length.ceil (frc.source);
+ if (video && !video->ignore()) {
+ double const vfr = _ffmpeg_content->video_frame_rate().get();
+ auto const f = full_length.frames_round (vfr);
+ auto const v = video->position(film()).get_value_or(ContentTime()).frames_round(vfr) + 1;
+ if (v < f) {
+ video->emit(film(), make_shared<const RawImageProxy>(_black_image), v);
+ did_something = true;
+ }
+ }
+
+ if (audio && !audio->ignore()) {
+ for (auto i: _ffmpeg_content->ffmpeg_audio_streams ()) {
+ auto const a = audio->stream_position(film(), i);
+ /* Unfortunately if a is 0 that really means that we don't know the stream position since
+ there has been no data on it since the last seek. In this case we'll just do nothing
+ here. I'm not sure if that's the right idea.
+ */
+ if (a > ContentTime() && a < full_length) {
+ LOG_DEBUG_PLAYER("Flush inserts silence at %1", to_string(a));
+ auto to_do = min (full_length - a, ContentTime::from_seconds (0.1));
+ auto silence = make_shared<AudioBuffers>(i->channels(), to_do.frames_ceil (i->frame_rate()));
+ silence->make_silent ();
+ audio->emit (film(), i, silence, a, true);
+ did_something = true;
+ }
+ }
+ }
+
+ return did_something ? FlushResult::AGAIN : FlushResult::DONE;
+}
+
+