- void playlist_changed ();
- void content_changed (boost::weak_ptr<Content>, int, bool);
- void do_seek (Time, bool);
- void flush ();
- void emit_black ();
- void emit_silence (OutputAudioFrame);
- boost::shared_ptr<Resampler> resampler (boost::shared_ptr<AudioContent>, bool);
- void film_changed (Film::Property);
- void update_subtitle ();
-
- boost::shared_ptr<const Film> _film;
- boost::shared_ptr<const Playlist> _playlist;
-
- bool _video;
- bool _audio;
-
- /** Our pieces are ready to go; if this is false the pieces must be (re-)created before they are used */
- bool _have_valid_pieces;
- std::list<boost::shared_ptr<Piece> > _pieces;
-
- /** The time after the last video that we emitted */
- Time _video_position;
- /** The time after the last audio that we emitted */
- Time _audio_position;
-
- AudioMerger<Time, AudioContent::Frame> _audio_merger;
-
- libdcp::Size _video_container_size;
- boost::shared_ptr<PlayerVideoFrame> _black_frame;
- std::map<boost::shared_ptr<AudioContent>, boost::shared_ptr<Resampler> > _resamplers;
-
- std::list<Subtitle> _subtitles;
-
-#ifdef DCPOMATIC_DEBUG
- boost::shared_ptr<Content> _last_video;
-#endif
+ void film_change (ChangeType, Film::Property);
+ void playlist_change (ChangeType);
+ void playlist_content_change (ChangeType, int, bool);
+ Frame dcp_to_content_video (std::shared_ptr<const Piece> piece, dcpomatic::DCPTime t) const;
+ dcpomatic::DCPTime content_video_to_dcp (std::shared_ptr<const Piece> piece, Frame f) const;
+ Frame dcp_to_resampled_audio (std::shared_ptr<const Piece> piece, dcpomatic::DCPTime t) const;
+ dcpomatic::DCPTime resampled_audio_to_dcp (std::shared_ptr<const Piece> piece, Frame f) const;
+ dcpomatic::ContentTime dcp_to_content_time (std::shared_ptr<const Piece> piece, dcpomatic::DCPTime t) const;
+ dcpomatic::DCPTime content_time_to_dcp (std::shared_ptr<const Piece> piece, dcpomatic::ContentTime t) const;
+ std::shared_ptr<PlayerVideo> black_player_video_frame (Eyes eyes) const;
+
+ void video (std::weak_ptr<Piece>, ContentVideo);
+ void audio (std::weak_ptr<Piece>, AudioStreamPtr, ContentAudio);
+ void bitmap_text_start (std::weak_ptr<Piece>, std::weak_ptr<const TextContent>, ContentBitmapText);
+ void plain_text_start (std::weak_ptr<Piece>, std::weak_ptr<const TextContent>, ContentStringText);
+ void subtitle_stop (std::weak_ptr<Piece>, std::weak_ptr<const TextContent>, dcpomatic::ContentTime);
+ void atmos (std::weak_ptr<Piece>, ContentAtmos);
+
+ dcpomatic::DCPTime one_video_frame () const;
+ void fill_audio (dcpomatic::DCPTimePeriod period);
+ std::pair<std::shared_ptr<AudioBuffers>, dcpomatic::DCPTime> discard_audio (
+ std::shared_ptr<const AudioBuffers> audio, dcpomatic::DCPTime time, dcpomatic::DCPTime discard_to
+ ) const;
+ boost::optional<PositionImage> open_subtitles_for_frame (dcpomatic::DCPTime time) const;
+ void emit_video (std::shared_ptr<PlayerVideo> pv, dcpomatic::DCPTime time);
+ void do_emit_video (std::shared_ptr<PlayerVideo> pv, dcpomatic::DCPTime time);
+ void emit_audio (std::shared_ptr<AudioBuffers> data, dcpomatic::DCPTime time);
+ std::shared_ptr<const Playlist> playlist () const;
+
+ /** Mutex to protect the most of the Player state. When it's used for the preview we have
+ seek() and pass() called from the Butler thread and lots of other stuff called
+ from the GUI thread.
+ */
+ mutable boost::mutex _mutex;
+
+ std::weak_ptr<const Film> _film;
+ /** Playlist, or 0 if we are using the one from the _film */
+ std::shared_ptr<const Playlist> _playlist;
+
+ /** > 0 if we are suspended (i.e. pass() and seek() do nothing) */
+ boost::atomic<int> _suspended;
+ std::list<std::shared_ptr<Piece>> _pieces;
+
+ /** Size of the image we are rendering to; this may be the DCP frame size, or
+ * the size of preview in a window.
+ */
+ boost::atomic<dcp::Size> _video_container_size;
+
+ mutable boost::mutex _black_image_mutex;
+ std::shared_ptr<Image> _black_image;
+
+ /** true if the player should ignore all video; i.e. never produce any */
+ boost::atomic<bool> _ignore_video;
+ boost::atomic<bool> _ignore_audio;
+ /** true if the player should ignore all text; i.e. never produce any */
+ boost::atomic<bool> _ignore_text;
+ boost::atomic<bool> _always_burn_open_subtitles;
+ /** true if we should try to be fast rather than high quality */
+ boost::atomic<bool> _fast;
+ /** true if we should keep going in the face of `survivable' errors */
+ bool _tolerant;
+ /** true if we should `play' (i.e output) referenced DCP data (e.g. for preview) */
+ boost::atomic<bool> _play_referenced;