summaryrefslogtreecommitdiff
path: root/chromium/media/base/text_renderer.h
blob: 532a1fa03762e642d3600372a2a0d272385ab4fb (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
143
144
145
// 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_track.h"

namespace base {
class MessageLoopProxy;
}

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:
  // |message_loop| 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::MessageLoopProxy>& message_loop,
               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;
  };

  // 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::MessageLoopProxy> message_loop_;
  base::WeakPtrFactory<TextRenderer> weak_factory_;
  base::WeakPtr<TextRenderer> weak_this_;
  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_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(TextRenderer);
};

}  // namespace media

#endif  // MEDIA_BASE_TEXT_RENDERER_H_