summaryrefslogtreecommitdiffstats
path: root/media/base/text_renderer.h
blob: 2888daf431c2a75bea8d368bcb22710deb13b84c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// 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/macros.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);

  // Stops all operations and fires all pending callbacks.
  ~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);

  // Starts text track cue decoding and rendering.
  void StartPlaying();

  // Temporarily suspends decoding and rendering, executing |callback| when
  // playback has been suspended.
  void Pause(const base::Closure& callback);

  // Discards any text data, executing |callback| when completed.
  void Flush(const base::Closure& callback);

  // Adds 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);

  // Removes |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_;

  // Simple state tracking variable.
  enum State {
    kUninitialized,
    kPausePending,
    kPaused,
    kPlaying,
    kEnded
  };
  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_