// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef MEDIA_BASE_TEXT_RENDERER_H_ #define MEDIA_BASE_TEXT_RENDERER_H_ #include <map> #include <set> #include "base/callback.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "media/base/demuxer_stream.h" #include "media/base/media_export.h" #include "media/base/pipeline_status.h" #include "media/base/text_ranges.h" #include "media/base/text_track.h" namespace base { class SingleThreadTaskRunner; } namespace media { class TextCue; class TextTrackConfig; // Receives decoder buffers from the upstream demuxer, decodes them to text // cues, and then passes them onto the TextTrack object associated with each // demuxer text stream. class MEDIA_EXPORT TextRenderer { public: // |task_runner| is the thread on which TextRenderer will execute. // // |add_text_track_cb] is called when the demuxer requests (via its host) // that a new text track be created. TextRenderer( const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, const AddTextTrackCB& add_text_track_cb); ~TextRenderer(); // |ended_cb| is executed when all of the text tracks have reached // end of stream, following a play request. void Initialize(const base::Closure& ended_cb); // Start text track cue decoding and rendering, executing |callback| when // playback is underway. void Play(const base::Closure& callback); // Temporarily suspend decoding and rendering, executing |callback| when // playback has been suspended. void Pause(const base::Closure& callback); // Discard any text data, executing |callback| when completed. void Flush(const base::Closure& callback); // Stop all operations in preparation for being deleted, executing |callback| // when complete. void Stop(const base::Closure& callback); // Add new |text_stream|, having the indicated |config|, to the text stream // collection managed by this text renderer. void AddTextStream(DemuxerStream* text_stream, const TextTrackConfig& config); // Remove |text_stream| from the text stream collection. void RemoveTextStream(DemuxerStream* text_stream); // Returns true if there are extant text tracks. bool HasTracks() const; private: struct TextTrackState { // To determine read progress. enum ReadState { kReadIdle, kReadPending }; explicit TextTrackState(scoped_ptr<TextTrack> text_track); ~TextTrackState(); ReadState read_state; scoped_ptr<TextTrack> text_track; TextRanges text_ranges_; }; // Callback delivered by the demuxer |text_stream| when // a read from the stream completes. void BufferReady(DemuxerStream* text_stream, DemuxerStream::Status status, const scoped_refptr<DecoderBuffer>& input); // Dispatches the decoded cue delivered on the demuxer's |text_stream|. void CueReady(DemuxerStream* text_stream, const scoped_refptr<TextCue>& text_cue); // Dispatched when the AddTextTrackCB completes, after having created // the TextTrack object associated with |text_stream|. void OnAddTextTrackDone(DemuxerStream* text_stream, scoped_ptr<TextTrack> text_track); // Utility function to post a read request on |text_stream|. void Read(TextTrackState* state, DemuxerStream* text_stream); scoped_refptr<base::SingleThreadTaskRunner> task_runner_; const AddTextTrackCB add_text_track_cb_; // Callbacks provided during Initialize(). base::Closure ended_cb_; // Callback provided to Pause(). base::Closure pause_cb_; // Callback provided to Stop(). base::Closure stop_cb_; // Simple state tracking variable. enum State { kUninitialized, kPausePending, kPaused, kPlaying, kEnded, kStopPending, kStopped }; State state_; typedef std::map<DemuxerStream*, TextTrackState*> TextTrackStateMap; TextTrackStateMap text_track_state_map_; // Indicates how many read requests are in flight. int pending_read_count_; // Indicates which text streams have not delivered end-of-stream yet. typedef std::set<DemuxerStream*> PendingEosSet; PendingEosSet pending_eos_set_; // NOTE: Weak pointers must be invalidated before all other member variables. base::WeakPtrFactory<TextRenderer> weak_factory_; DISALLOW_IMPLICIT_CONSTRUCTORS(TextRenderer); }; } // namespace media #endif // MEDIA_BASE_TEXT_RENDERER_H_