- boost::shared_ptr<AudioBuffers> deinterleave_audio (uint8_t** data, int size);
-
- bool seek_overrun_finished (ContentTime, boost::optional<ContentTime>, boost::optional<ContentTime>) const;
- bool seek_final_finished (int, int) const;
- int minimal_run (boost::function<bool (boost::optional<ContentTime>, boost::optional<ContentTime>, int)>);
- void seek_and_flush (ContentTime);
-
- bool has_subtitle_during (ContentTimePeriod) const;
-
- boost::shared_ptr<Log> _log;
- AVCodecContext* _subtitle_codec_context; ///< may be 0 if there is no subtitle
- AVCodec* _subtitle_codec; ///< may be 0 if there is no subtitle
-
- std::list<boost::shared_ptr<FilterGraph> > _filter_graphs;
- boost::mutex _filter_graphs_mutex;
-
- ContentTime _pts_offset;
+
+ FlushResult flush_codecs();
+ FlushResult flush_fill();
+
+ VideoFilterGraphSet _filter_graphs;
+
+ dcpomatic::ContentTime _pts_offset;
+ boost::optional<dcpomatic::ContentTime> _current_subtitle_to;
+ /** true if we have a subtitle which has not had emit_stop called for it yet */
+ bool _have_current_subtitle = false;
+
+ std::shared_ptr<Image> _black_image;
+
+ std::map<std::shared_ptr<FFmpegAudioStream>, boost::optional<dcpomatic::ContentTime>> _next_time;
+
+ enum class FlushState {
+ CODECS,
+ AUDIO_DECODER,
+ FILL,
+ };
+
+ FlushState _flush_state = FlushState::CODECS;