Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(282)

Side by Side Diff: media/filters/text_renderer_impl.cc

Issue 23702007: Render inband text tracks in the media pipeline (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 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 #include "media/filters/text_renderer_impl.h"
6
7 #include "base/bind.h"
8 #include "base/callback_helpers.h"
9 #include "base/logging.h"
10 #include "base/message_loop/message_loop_proxy.h"
11 #include "media/base/demuxer.h"
12 #include "media/base/demuxer_stream.h"
13 #include "media/base/text_buffer.h"
14 #include "media/base/text_decoder.h"
15
16 namespace media {
17
18 TextRendererImpl::TextRendererImpl(
19 const scoped_refptr<base::MessageLoopProxy>& message_loop,
20 scoped_ptr<TextDecoder> decoder,
21 const CueReadyCB& cue_ready_cb)
22 : message_loop_(message_loop),
23 weak_factory_(this),
24 decoder_(decoder.Pass()),
25 cue_ready_cb_(cue_ready_cb),
26 state_(kUninitialized),
27 text_stream_count_(0),
28 pending_read_count_(0),
29 eos_count_(0) {
30 }
31
32 TextRendererImpl::~TextRendererImpl() {
33 DCHECK(state_ == kUninitialized || state_ == kStopped);
34 DCHECK_EQ(pending_read_count_, 0);
35 }
36
37 void TextRendererImpl::Initialize(Demuxer* demuxer,
38 const PipelineStatusCB& init_cb,
39 const base::Closure& ended_cb) {
40 DCHECK(message_loop_->BelongsToCurrentThread());
41 DCHECK_NE(demuxer, static_cast<Demuxer*>(NULL));
42 DCHECK(!init_cb.is_null());
43 DCHECK(!ended_cb.is_null());
44 DCHECK_EQ(kUninitialized, state_);
45 DCHECK_EQ(text_stream_count_, 0);
46 DCHECK_EQ(pending_read_count_, 0);
47 DCHECK_EQ(eos_count_, 0);
48 DCHECK(init_cb_.is_null());
49 DCHECK(ended_cb_.is_null());
50
51 weak_this_ = weak_factory_.GetWeakPtr();
52 init_cb_ = init_cb;
53 ended_cb_ = ended_cb;
54
55 decoder_->Initialize(demuxer);
56
57 const int stream_count = demuxer->GetStreamCount();
58 read_state_.reserve(stream_count);
59
60 for (int idx = 0; idx < stream_count; ++idx) {
61 DemuxerStream* stream = demuxer->GetStreamByIndex(idx);
62 if (stream == NULL || stream->type() != DemuxerStream::TEXT) {
63 read_state_.push_back(kReadInactive);
64 } else {
65 read_state_.push_back(kReadIdle);
66 ++text_stream_count_;
67 }
68 }
69
70 // Start the machine in the stopped state. We transition out
71 // of the stopped state via a Pause() or Play() request.
72 state_ = kStopped;
acolwell GONE FROM CHROMIUM 2013/09/12 00:15:15 It seems like state_ = kPaused and eos_count_ = te
Matthew Heaney (Chromium) 2013/09/13 19:51:54 Done.
73
74 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
acolwell GONE FROM CHROMIUM 2013/09/12 00:15:15 This method doesn't look like it actually needs to
Matthew Heaney (Chromium) 2013/09/13 19:51:54 Done.
75 }
76
77 void TextRendererImpl::Play(const base::Closure& callback) {
78 DCHECK(message_loop_->BelongsToCurrentThread());
79 base::AutoLock auto_lock(lock_);
80 DCHECK_NE(state_, kUninitialized);
acolwell GONE FROM CHROMIUM 2013/09/12 00:15:15 nit: Remove since the DCHECK below is more specifi
Matthew Heaney (Chromium) 2013/09/13 19:51:54 Done.
81 DCHECK(state_ == kPaused || state_ == kStopped);
82
83 if (state_ == kStopped)
84 eos_count_ = text_stream_count_;
85
86 state_ = kPlaying;
87 callback.Run();
88
89 for (std::vector<ReadState>::size_type idx = 0;
90 idx < read_state_.size(); ++idx) {
91 if (read_state_[idx] == kReadInactive)
92 continue;
93
94 if (read_state_[idx] == kReadPending) {
95 DCHECK_GT(pending_read_count_, 0);
96 continue;
97 }
98
99 read_state_[idx] = kReadPending;
100 ++pending_read_count_;
101 decoder_->Read(idx, base::Bind(&TextRendererImpl::CueReady, weak_this_));
102 }
103 }
104
105 void TextRendererImpl::Pause(const base::Closure& callback) {
106 DCHECK(message_loop_->BelongsToCurrentThread());
107 base::AutoLock auto_lock(lock_);
108 DCHECK_NE(state_, kUninitialized);
109 DCHECK_NE(state_, kStopPending);
110 pause_cb_ = callback;
111
112 if (state_ == kStopped) {
113 eos_count_ = text_stream_count_;
acolwell GONE FROM CHROMIUM 2013/09/12 00:15:15 Why is this line here? This doesn't feel right to
Matthew Heaney (Chromium) 2013/09/13 19:51:54 Done.
114 state_ = kPaused;
115 base::ResetAndReturn(&pause_cb_).Run();
116 return;
117 }
118
119 if (state_ == kPaused) {
acolwell GONE FROM CHROMIUM 2013/09/12 00:15:15 You shouldn't get a Pause() call if you are alread
Matthew Heaney (Chromium) 2013/09/13 19:51:54 Done.
120 DCHECK_EQ(pending_read_count_, 0);
121 base::ResetAndReturn(&pause_cb_).Run();
122 return;
123 }
124
125 if (state_ == kPausePending)
acolwell GONE FROM CHROMIUM 2013/09/12 00:15:15 You shouldn't get another Pause() call if the curr
Matthew Heaney (Chromium) 2013/09/13 19:51:54 Done.
126 return;
127
128 if (pending_read_count_ <= 0) {
129 state_ = kPaused;
130 base::ResetAndReturn(&pause_cb_).Run();
131 return;
132 }
133
134 state_ = kPausePending;
135 }
136
acolwell GONE FROM CHROMIUM 2013/09/12 00:15:15 It seems like you would need a Flush() method so t
Matthew Heaney (Chromium) 2013/09/13 19:51:54 Done.
137 void TextRendererImpl::Stop(const base::Closure& cb) {
138 DCHECK(message_loop_->BelongsToCurrentThread());
139 DCHECK(!cb.is_null());
140 base::AutoLock auto_lock(lock_);
141 DCHECK_NE(state_, kUninitialized);
142
143 stop_cb_ = cb;
144
145 if (state_ == kStopped) {
acolwell GONE FROM CHROMIUM 2013/09/12 00:15:15 You shound't get a stop if you have already receiv
Matthew Heaney (Chromium) 2013/09/13 19:51:54 Done.
146 DCHECK_EQ(pending_read_count_, 0);
147 base::ResetAndReturn(&stop_cb_).Run();
148 return;
149 }
150
151 if (state_ == kStopPending) {
acolwell GONE FROM CHROMIUM 2013/09/12 00:15:15 You should not get a Stop() if the previous one is
Matthew Heaney (Chromium) 2013/09/13 19:51:54 Done.
152 DCHECK_GT(pending_read_count_, 0);
153 stop_cb_ = cb;
154 return;
155 }
156
157 if (pending_read_count_ <= 0) {
158 state_ = kStopped;
159 base::ResetAndReturn(&stop_cb_).Run();
160 return;
161 }
162
163 state_ = kStopPending;
164 }
165
166 void TextRendererImpl::CueReady(
167 int index,
168 const scoped_refptr<TextBuffer>& buffer) {
169 base::AutoLock auto_lock(lock_);
170 DCHECK_NE(state_, kUninitialized);
acolwell GONE FROM CHROMIUM 2013/09/12 00:15:15 can't you DCHECK(message_loop_->BelongsToCurrentTh
Matthew Heaney (Chromium) 2013/09/13 19:51:54 Done.
171 DCHECK_NE(state_, kStopped);
172 DCHECK_GT(pending_read_count_, 0);
173 DCHECK_GT(eos_count_, 0);
174 DCHECK_EQ(read_state_[index], kReadPending);
175
176 --pending_read_count_;
177 read_state_[index] = kReadIdle;
178
179 switch (state_) {
180 case kPlaying:
181 if (buffer.get())
acolwell GONE FROM CHROMIUM 2013/09/12 00:15:15 nit: You shouldn't need the get()
Matthew Heaney (Chromium) 2013/09/13 19:51:54 Done.
182 break;
183
184 // A NULL buffer means that we have reached EOS (or there's an error).
185
186 --eos_count_;
187
188 if (pending_read_count_ > 0)
acolwell GONE FROM CHROMIUM 2013/09/12 00:15:15 DCHECK
Matthew Heaney (Chromium) 2013/09/13 19:51:54 Multiple read requests can be pending simultaneous
acolwell GONE FROM CHROMIUM 2013/09/13 20:57:30 Ok. Right. I don't know what I was thinking here.
189 return;
190
191 if (eos_count_ <= 0) {
192 state_ = kStopped;
acolwell GONE FROM CHROMIUM 2013/09/12 00:15:15 it seems like an kEnded state would be more approp
Matthew Heaney (Chromium) 2013/09/13 19:51:54 Done.
193 ended_cb_.Run();
194 }
195
196 return;
197
198 case kPausePending:
199 if (pending_read_count_ <= 0) {
200 state_ = kPaused;
201 pause_cb_.Run();
202 }
203
204 return;
205
206 case kStopPending:
207 if (pending_read_count_ <= 0) {
208 state_ = kStopped;
209 stop_cb_.Run();
210 }
211
212 return;
213
214 case kPaused:
215 case kStopped:
216 case kUninitialized:
217 default:
218 NOTREACHED();
219 return;
220 }
221
222 cue_ready_cb_.Run(index, buffer);
223
224 read_state_[index] = kReadPending;
225 ++pending_read_count_;
226 decoder_->Read(index, base::Bind(&TextRendererImpl::CueReady, weak_this_));
227 }
228
229 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698