1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef MEDIA_BASE_TEXT_RENDERER_H_
6 #define MEDIA_BASE_TEXT_RENDERER_H_
7 
8 #include <map>
9 #include <memory>
10 #include <set>
11 
12 #include "base/callback.h"
13 #include "base/macros.h"
14 #include "base/memory/weak_ptr.h"
15 #include "media/base/demuxer_stream.h"
16 #include "media/base/media_export.h"
17 #include "media/base/pipeline_status.h"
18 #include "media/base/text_ranges.h"
19 #include "media/base/text_track.h"
20 
21 namespace base {
22 class SingleThreadTaskRunner;
23 }
24 
25 namespace media {
26 
27 class TextCue;
28 class TextTrackConfig;
29 
30 // Receives decoder buffers from the upstream demuxer, decodes them to text
31 // cues, and then passes them onto the TextTrack object associated with each
32 // demuxer text stream.
33 class MEDIA_EXPORT TextRenderer {
34  public:
35   // |task_runner| is the thread on which TextRenderer will execute.
36   //
37   // |add_text_track_cb] is called when the demuxer requests (via its host)
38   // that a new text track be created.
39   TextRenderer(
40       const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
41       const AddTextTrackCB& add_text_track_cb);
42 
43   // Stops all operations and fires all pending callbacks.
44   ~TextRenderer();
45 
46   // |ended_cb| is executed when all of the text tracks have reached
47   // end of stream, following a play request.
48   void Initialize(const base::RepeatingClosure& ended_cb);
49 
50   // Starts text track cue decoding and rendering.
51   void StartPlaying();
52 
53   // Temporarily suspends decoding and rendering, executing |callback| when
54   // playback has been suspended.
55   void Pause(base::OnceClosure callback);
56 
57   // Discards any text data, executing |callback| when completed.
58   void Flush(base::OnceClosure callback);
59 
60   // Adds new |text_stream|, having the indicated |config|, to the text stream
61   // collection managed by this text renderer.
62   void AddTextStream(DemuxerStream* text_stream,
63                      const TextTrackConfig& config);
64 
65   // Removes |text_stream| from the text stream collection.
66   void RemoveTextStream(DemuxerStream* text_stream);
67 
68   // Returns true if there are extant text tracks.
69   bool HasTracks() const;
70 
71  private:
72   struct TextTrackState {
73     // To determine read progress.
74     enum ReadState {
75       kReadIdle,
76       kReadPending
77     };
78 
79     explicit TextTrackState(std::unique_ptr<TextTrack> text_track);
80     ~TextTrackState();
81 
82     ReadState read_state;
83     std::unique_ptr<TextTrack> text_track;
84     TextRanges text_ranges_;
85   };
86 
87   // Callback delivered by the demuxer |text_stream| when
88   // a read from the stream completes.
89   void BufferReady(DemuxerStream* text_stream,
90                    DemuxerStream::Status status,
91                    scoped_refptr<DecoderBuffer> input);
92 
93   // Dispatches the decoded cue delivered on the demuxer's |text_stream|.
94   void CueReady(DemuxerStream* text_stream,
95                 const scoped_refptr<TextCue>& text_cue);
96 
97   // Dispatched when the AddTextTrackCB completes, after having created
98   // the TextTrack object associated with |text_stream|.
99   void OnAddTextTrackDone(DemuxerStream* text_stream,
100                           std::unique_ptr<TextTrack> text_track);
101 
102   // Utility function to post a read request on |text_stream|.
103   void Read(TextTrackState* state, DemuxerStream* text_stream);
104 
105   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
106   const AddTextTrackCB add_text_track_cb_;
107 
108   // Callbacks provided during Initialize().
109   base::RepeatingClosure ended_cb_;
110 
111   // Callback provided to Pause().
112   base::OnceClosure pause_cb_;
113 
114   // Simple state tracking variable.
115   enum State {
116     kUninitialized,
117     kPausePending,
118     kPaused,
119     kPlaying,
120     kEnded
121   };
122   State state_;
123 
124   std::map<DemuxerStream*, std::unique_ptr<TextTrackState>>
125       text_track_state_map_;
126 
127   // Indicates how many read requests are in flight.
128   int pending_read_count_;
129 
130   // Indicates which text streams have not delivered end-of-stream yet.
131   typedef std::set<DemuxerStream*> PendingEosSet;
132   PendingEosSet pending_eos_set_;
133 
134   // NOTE: Weak pointers must be invalidated before all other member variables.
135   base::WeakPtrFactory<TextRenderer> weak_factory_{this};
136 
137   DISALLOW_IMPLICIT_CONSTRUCTORS(TextRenderer);
138 };
139 
140 }  // namespace media
141 
142 #endif  // MEDIA_BASE_TEXT_RENDERER_H_
143