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