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

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

Issue 239893002: Allow multiple concurrent Decode() requests in VideoDecoder interface. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « media/filters/decoder_stream.h ('k') | media/filters/fake_demuxer_stream.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/filters/decoder_stream.h" 5 #include "media/filters/decoder_stream.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback_helpers.h" 8 #include "base/callback_helpers.h"
9 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "base/location.h" 10 #include "base/location.h"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 ScopedVector<Decoder> decoders, 44 ScopedVector<Decoder> decoders,
45 const SetDecryptorReadyCB& set_decryptor_ready_cb) 45 const SetDecryptorReadyCB& set_decryptor_ready_cb)
46 : task_runner_(task_runner), 46 : task_runner_(task_runner),
47 state_(STATE_UNINITIALIZED), 47 state_(STATE_UNINITIALIZED),
48 stream_(NULL), 48 stream_(NULL),
49 decoder_selector_( 49 decoder_selector_(
50 new DecoderSelector<StreamType>(task_runner, 50 new DecoderSelector<StreamType>(task_runner,
51 decoders.Pass(), 51 decoders.Pass(),
52 set_decryptor_ready_cb)), 52 set_decryptor_ready_cb)),
53 active_splice_(false), 53 active_splice_(false),
54 pending_decode_requests_(0),
54 weak_factory_(this) {} 55 weak_factory_(this) {}
55 56
56 template <DemuxerStream::Type StreamType> 57 template <DemuxerStream::Type StreamType>
57 DecoderStream<StreamType>::~DecoderStream() { 58 DecoderStream<StreamType>::~DecoderStream() {
58 DCHECK(state_ == STATE_UNINITIALIZED || state_ == STATE_STOPPED) << state_; 59 DCHECK(state_ == STATE_UNINITIALIZED || state_ == STATE_STOPPED) << state_;
59 } 60 }
60 61
61 template <DemuxerStream::Type StreamType> 62 template <DemuxerStream::Type StreamType>
62 void DecoderStream<StreamType>::Initialize(DemuxerStream* stream, 63 void DecoderStream<StreamType>::Initialize(DemuxerStream* stream,
63 bool low_delay, 64 bool low_delay,
(...skipping 16 matching lines...) Expand all
80 stream, low_delay, 81 stream, low_delay,
81 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected, 82 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected,
82 weak_factory_.GetWeakPtr())); 83 weak_factory_.GetWeakPtr()));
83 } 84 }
84 85
85 template <DemuxerStream::Type StreamType> 86 template <DemuxerStream::Type StreamType>
86 void DecoderStream<StreamType>::Read(const ReadCB& read_cb) { 87 void DecoderStream<StreamType>::Read(const ReadCB& read_cb) {
87 FUNCTION_DVLOG(2); 88 FUNCTION_DVLOG(2);
88 DCHECK(task_runner_->BelongsToCurrentThread()); 89 DCHECK(task_runner_->BelongsToCurrentThread());
89 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || 90 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
90 state_ == STATE_ERROR) << state_; 91 state_ == STATE_ERROR || state_ == STATE_REINITIALIZING_DECODER ||
92 state_ == STATE_PENDING_DEMUXER_READ)
93 << state_;
91 // No two reads in the flight at any time. 94 // No two reads in the flight at any time.
92 DCHECK(read_cb_.is_null()); 95 DCHECK(read_cb_.is_null());
93 // No read during resetting or stopping process. 96 // No read during resetting or stopping process.
94 DCHECK(reset_cb_.is_null()); 97 DCHECK(reset_cb_.is_null());
95 DCHECK(stop_cb_.is_null()); 98 DCHECK(stop_cb_.is_null());
96 99
100 read_cb_ = read_cb;
101
97 if (state_ == STATE_ERROR) { 102 if (state_ == STATE_ERROR) {
98 task_runner_->PostTask(FROM_HERE, base::Bind( 103 task_runner_->PostTask(FROM_HERE,
99 read_cb, DECODE_ERROR, scoped_refptr<Output>())); 104 base::Bind(base::ResetAndReturn(&read_cb_),
105 DECODE_ERROR,
106 scoped_refptr<Output>()));
100 return; 107 return;
101 } 108 }
102 109
103 read_cb_ = read_cb; 110 if (!ready_outputs_.empty()) {
111 task_runner_->PostTask(FROM_HERE, base::Bind(
112 base::ResetAndReturn(&read_cb_), OK, ready_outputs_.front()));
113 ready_outputs_.pop_front();
114 }
115
116 // Decoder may be in reinitializing state as result of the previous Read().
117 if (state_ == STATE_REINITIALIZING_DECODER)
118 return;
119
120 if (!CanDecodeMore())
121 return;
104 122
105 if (state_ == STATE_FLUSHING_DECODER) { 123 if (state_ == STATE_FLUSHING_DECODER) {
106 FlushDecoder(); 124 FlushDecoder();
107 return; 125 return;
108 } 126 }
109 127
110 scoped_refptr<Output> output = decoder_->GetDecodeOutput(); 128 if (state_ != STATE_PENDING_DEMUXER_READ)
111 129 ReadFromDemuxerStream();
112 // If the decoder has queued output ready to go we don't need a demuxer read.
113 if (output) {
114 task_runner_->PostTask(
115 FROM_HERE, base::Bind(base::ResetAndReturn(&read_cb_), OK, output));
116 return;
117 }
118
119 ReadFromDemuxerStream();
120 } 130 }
121 131
122 template <DemuxerStream::Type StreamType> 132 template <DemuxerStream::Type StreamType>
123 void DecoderStream<StreamType>::Reset(const base::Closure& closure) { 133 void DecoderStream<StreamType>::Reset(const base::Closure& closure) {
124 FUNCTION_DVLOG(2); 134 FUNCTION_DVLOG(2);
125 DCHECK(task_runner_->BelongsToCurrentThread()); 135 DCHECK(task_runner_->BelongsToCurrentThread());
126 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_; 136 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_;
127 DCHECK(reset_cb_.is_null()); 137 DCHECK(reset_cb_.is_null());
128 DCHECK(stop_cb_.is_null()); 138 DCHECK(stop_cb_.is_null());
129 139
130 reset_cb_ = closure; 140 reset_cb_ = closure;
131 141
142 if (!read_cb_.is_null()) {
143 task_runner_->PostTask(FROM_HERE, base::Bind(
144 base::ResetAndReturn(&read_cb_), ABORTED, scoped_refptr<Output>()));
145 }
146
147 ready_outputs_.clear();
148
132 // During decoder reinitialization, the Decoder does not need to be and 149 // During decoder reinitialization, the Decoder does not need to be and
133 // cannot be Reset(). |decrypting_demuxer_stream_| was reset before decoder 150 // cannot be Reset(). |decrypting_demuxer_stream_| was reset before decoder
134 // reinitialization. 151 // reinitialization.
135 if (state_ == STATE_REINITIALIZING_DECODER) 152 if (state_ == STATE_REINITIALIZING_DECODER)
136 return; 153 return;
137 154
138 // During pending demuxer read and when not using DecryptingDemuxerStream, 155 // During pending demuxer read and when not using DecryptingDemuxerStream,
139 // the Decoder will be reset after demuxer read is returned 156 // the Decoder will be reset after demuxer read is returned
140 // (in OnBufferReady()). 157 // (in OnBufferReady()).
141 if (state_ == STATE_PENDING_DEMUXER_READ && !decrypting_demuxer_stream_) 158 if (state_ == STATE_PENDING_DEMUXER_READ && !decrypting_demuxer_stream_)
142 return; 159 return;
143 160
144 // The Decoder API guarantees that if Decoder::Reset() is called during
145 // a pending decode, the decode callback must be fired before the reset
146 // callback is fired. Therefore, we can call Decoder::Reset() regardless
147 // of if we have a pending decode and always satisfy the reset callback when
148 // the decoder reset is finished.
149 if (decrypting_demuxer_stream_) { 161 if (decrypting_demuxer_stream_) {
150 decrypting_demuxer_stream_->Reset(base::Bind( 162 decrypting_demuxer_stream_->Reset(base::Bind(
151 &DecoderStream<StreamType>::ResetDecoder, weak_factory_.GetWeakPtr())); 163 &DecoderStream<StreamType>::ResetDecoder, weak_factory_.GetWeakPtr()));
152 return; 164 return;
153 } 165 }
154 166
155 ResetDecoder(); 167 ResetDecoder();
156 } 168 }
157 169
158 template <DemuxerStream::Type StreamType> 170 template <DemuxerStream::Type StreamType>
159 void DecoderStream<StreamType>::Stop(const base::Closure& closure) { 171 void DecoderStream<StreamType>::Stop(const base::Closure& closure) {
160 FUNCTION_DVLOG(2); 172 FUNCTION_DVLOG(2);
161 DCHECK(task_runner_->BelongsToCurrentThread()); 173 DCHECK(task_runner_->BelongsToCurrentThread());
162 DCHECK_NE(state_, STATE_STOPPED) << state_; 174 DCHECK_NE(state_, STATE_STOPPED) << state_;
163 DCHECK(stop_cb_.is_null()); 175 DCHECK(stop_cb_.is_null());
164 176
165 stop_cb_ = closure; 177 stop_cb_ = closure;
166 178
167 if (state_ == STATE_INITIALIZING) { 179 if (state_ == STATE_INITIALIZING) {
168 decoder_selector_->Abort(); 180 decoder_selector_->Abort();
169 return; 181 return;
170 } 182 }
171 183
172 DCHECK(init_cb_.is_null()); 184 DCHECK(init_cb_.is_null());
173 185
174 // All pending callbacks will be dropped. 186 // All pending callbacks will be dropped.
175 weak_factory_.InvalidateWeakPtrs(); 187 weak_factory_.InvalidateWeakPtrs();
176 188
177 // Post callbacks to prevent reentrance into this object. 189 // Post callbacks to prevent reentrance into this object.
178 if (!read_cb_.is_null()) 190 if (!read_cb_.is_null()) {
179 task_runner_->PostTask(FROM_HERE, base::Bind( 191 task_runner_->PostTask(FROM_HERE, base::Bind(
180 base::ResetAndReturn(&read_cb_), ABORTED, scoped_refptr<Output>())); 192 base::ResetAndReturn(&read_cb_), ABORTED, scoped_refptr<Output>()));
193 }
181 if (!reset_cb_.is_null()) 194 if (!reset_cb_.is_null())
182 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&reset_cb_)); 195 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&reset_cb_));
183 196
184 if (decrypting_demuxer_stream_) { 197 if (decrypting_demuxer_stream_) {
185 decrypting_demuxer_stream_->Stop(base::Bind( 198 decrypting_demuxer_stream_->Stop(base::Bind(
186 &DecoderStream<StreamType>::StopDecoder, weak_factory_.GetWeakPtr())); 199 &DecoderStream<StreamType>::StopDecoder, weak_factory_.GetWeakPtr()));
187 return; 200 return;
188 } 201 }
189 202
190 // We may not have a |decoder_| if Stop() was called during initialization. 203 // We may not have a |decoder_| if Stop() was called during initialization.
(...skipping 15 matching lines...) Expand all
206 return decoder_->CanReadWithoutStalling(); 219 return decoder_->CanReadWithoutStalling();
207 } 220 }
208 221
209 template <> 222 template <>
210 bool DecoderStream<DemuxerStream::AUDIO>::CanReadWithoutStalling() const { 223 bool DecoderStream<DemuxerStream::AUDIO>::CanReadWithoutStalling() const {
211 DCHECK(task_runner_->BelongsToCurrentThread()); 224 DCHECK(task_runner_->BelongsToCurrentThread());
212 return true; 225 return true;
213 } 226 }
214 227
215 template <DemuxerStream::Type StreamType> 228 template <DemuxerStream::Type StreamType>
229 bool DecoderStream<StreamType>::CanDecodeMore() const {
230 DCHECK(task_runner_->BelongsToCurrentThread());
231
232 // Limit total number of outputs stored in |ready_outputs_| and being decoded.
233 // It only makes sense to saturate decoder completely when output queue is
234 // empty.
235 int num_decodes =
236 static_cast<int>(ready_outputs_.size()) + pending_decode_requests_;
237 return num_decodes < decoder_->GetMaxDecodeRequests();
238 }
239
240 template <>
241 bool DecoderStream<DemuxerStream::AUDIO>::CanDecodeMore() const {
242 DCHECK(task_runner_->BelongsToCurrentThread());
243 return !pending_decode_requests_ && ready_outputs_.empty();
244 }
245
246 template <DemuxerStream::Type StreamType>
216 void DecoderStream<StreamType>::OnDecoderSelected( 247 void DecoderStream<StreamType>::OnDecoderSelected(
217 scoped_ptr<Decoder> selected_decoder, 248 scoped_ptr<Decoder> selected_decoder,
218 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) { 249 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) {
219 FUNCTION_DVLOG(2); 250 FUNCTION_DVLOG(2);
220 DCHECK(task_runner_->BelongsToCurrentThread()); 251 DCHECK(task_runner_->BelongsToCurrentThread());
221 DCHECK_EQ(state_, STATE_INITIALIZING) << state_; 252 DCHECK_EQ(state_, STATE_INITIALIZING) << state_;
222 DCHECK(!init_cb_.is_null()); 253 DCHECK(!init_cb_.is_null());
223 DCHECK(read_cb_.is_null()); 254 DCHECK(read_cb_.is_null());
224 DCHECK(reset_cb_.is_null()); 255 DCHECK(reset_cb_.is_null());
225 256
(...skipping 22 matching lines...) Expand all
248 279
249 template <DemuxerStream::Type StreamType> 280 template <DemuxerStream::Type StreamType>
250 void DecoderStream<StreamType>::SatisfyRead( 281 void DecoderStream<StreamType>::SatisfyRead(
251 Status status, 282 Status status,
252 const scoped_refptr<Output>& output) { 283 const scoped_refptr<Output>& output) {
253 DCHECK(!read_cb_.is_null()); 284 DCHECK(!read_cb_.is_null());
254 base::ResetAndReturn(&read_cb_).Run(status, output); 285 base::ResetAndReturn(&read_cb_).Run(status, output);
255 } 286 }
256 287
257 template <DemuxerStream::Type StreamType> 288 template <DemuxerStream::Type StreamType>
258 void DecoderStream<StreamType>::AbortRead() {
259 // Abort read during pending reset. It is safe to fire the |read_cb_| directly
260 // instead of posting it because the renderer won't call into this class
261 // again when it's in kFlushing state.
262 // TODO(xhwang): Improve the resetting process to avoid this dependency on the
263 // caller.
264 DCHECK(!reset_cb_.is_null());
265 SatisfyRead(ABORTED, NULL);
266 }
267
268 template <DemuxerStream::Type StreamType>
269 void DecoderStream<StreamType>::Decode( 289 void DecoderStream<StreamType>::Decode(
270 const scoped_refptr<DecoderBuffer>& buffer) { 290 const scoped_refptr<DecoderBuffer>& buffer) {
271 FUNCTION_DVLOG(2); 291 FUNCTION_DVLOG(2);
272 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_; 292 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_;
273 DCHECK(!read_cb_.is_null()); 293 DCHECK(CanDecodeMore());
274 DCHECK(reset_cb_.is_null()); 294 DCHECK(reset_cb_.is_null());
275 DCHECK(stop_cb_.is_null()); 295 DCHECK(stop_cb_.is_null());
276 DCHECK(buffer); 296 DCHECK(buffer);
277 297
278 int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size(); 298 int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size();
279 299
280 TRACE_EVENT_ASYNC_BEGIN0("media", GetTraceString<StreamType>(), this); 300 TRACE_EVENT_ASYNC_BEGIN0("media", GetTraceString<StreamType>(), this);
301 ++pending_decode_requests_;
281 decoder_->Decode(buffer, 302 decoder_->Decode(buffer,
282 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, 303 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady,
283 weak_factory_.GetWeakPtr(), 304 weak_factory_.GetWeakPtr(),
284 buffer_size)); 305 buffer_size));
285 } 306 }
286 307
287 template <DemuxerStream::Type StreamType> 308 template <DemuxerStream::Type StreamType>
288 void DecoderStream<StreamType>::FlushDecoder() { 309 void DecoderStream<StreamType>::FlushDecoder() {
289 Decode(DecoderBuffer::CreateEOSBuffer()); 310 if (pending_decode_requests_ == 0)
311 Decode(DecoderBuffer::CreateEOSBuffer());
290 } 312 }
291 313
292 template <DemuxerStream::Type StreamType> 314 template <DemuxerStream::Type StreamType>
293 void DecoderStream<StreamType>::OnDecodeOutputReady( 315 void DecoderStream<StreamType>::OnDecodeOutputReady(
294 int buffer_size, 316 int buffer_size,
295 typename Decoder::Status status, 317 typename Decoder::Status status,
296 const scoped_refptr<Output>& output) { 318 const scoped_refptr<Output>& output) {
297 FUNCTION_DVLOG(2); 319 FUNCTION_DVLOG(2) << status << " " << output;
298 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_; 320 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
299 DCHECK(!read_cb_.is_null()); 321 state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR)
322 << state_;
300 DCHECK(stop_cb_.is_null()); 323 DCHECK(stop_cb_.is_null());
301 DCHECK_EQ(status == Decoder::kOk, output != NULL); 324 DCHECK_EQ(status == Decoder::kOk, output != NULL);
325 DCHECK_GT(pending_decode_requests_, 0);
326
327 --pending_decode_requests_;
302 328
303 TRACE_EVENT_ASYNC_END0("media", GetTraceString<StreamType>(), this); 329 TRACE_EVENT_ASYNC_END0("media", GetTraceString<StreamType>(), this);
304 330
331 if (state_ == STATE_ERROR) {
332 DCHECK(read_cb_.is_null());
333 return;
334 }
335
305 if (status == Decoder::kDecodeError) { 336 if (status == Decoder::kDecodeError) {
306 state_ = STATE_ERROR; 337 state_ = STATE_ERROR;
307 SatisfyRead(DECODE_ERROR, NULL); 338 ready_outputs_.clear();
339 if (!read_cb_.is_null())
340 SatisfyRead(DECODE_ERROR, NULL);
308 return; 341 return;
309 } 342 }
310 343
311 if (status == Decoder::kDecryptError) { 344 if (status == Decoder::kDecryptError) {
312 state_ = STATE_ERROR; 345 state_ = STATE_ERROR;
313 SatisfyRead(DECRYPT_ERROR, NULL); 346 ready_outputs_.clear();
347 if (!read_cb_.is_null())
348 SatisfyRead(DECRYPT_ERROR, NULL);
314 return; 349 return;
315 } 350 }
316 351
317 if (status == Decoder::kAborted) { 352 if (status == Decoder::kAborted) {
318 SatisfyRead(ABORTED, NULL); 353 if (!read_cb_.is_null())
354 SatisfyRead(ABORTED, NULL);
319 return; 355 return;
320 } 356 }
321 357
322 // Any successful decode counts! 358 // Any successful decode counts!
323 if (buffer_size > 0) { 359 if (buffer_size > 0) {
324 StreamTraits::ReportStatistics(statistics_cb_, buffer_size); 360 StreamTraits::ReportStatistics(statistics_cb_, buffer_size);
325 } 361 }
326 362
327 // Drop decoding result if Reset() was called during decoding. 363 // Drop decoding result if Reset() was called during decoding.
328 // The resetting process will be handled when the decoder is reset. 364 // The resetting process will be handled when the decoder is reset.
329 if (!reset_cb_.is_null()) { 365 if (!reset_cb_.is_null())
330 AbortRead();
331 return; 366 return;
332 }
333 367
334 // Decoder flushed. Reinitialize the decoder. 368 // Decoder flushed. Reinitialize the decoder.
335 if (state_ == STATE_FLUSHING_DECODER && 369 if (state_ == STATE_FLUSHING_DECODER &&
336 status == Decoder::kOk && output->end_of_stream()) { 370 status == Decoder::kOk && output->end_of_stream()) {
337 ReinitializeDecoder(); 371 ReinitializeDecoder();
338 return; 372 return;
339 } 373 }
340 374
341 if (status == Decoder::kNotEnoughData) { 375 if (status == Decoder::kNotEnoughData) {
342 if (state_ == STATE_NORMAL) 376 if (state_ == STATE_NORMAL)
343 ReadFromDemuxerStream(); 377 ReadFromDemuxerStream();
344 else if (state_ == STATE_FLUSHING_DECODER) 378 else if (state_ == STATE_FLUSHING_DECODER)
345 FlushDecoder(); 379 FlushDecoder();
346 return; 380 return;
347 } 381 }
348 382
349 DCHECK(output); 383 DCHECK(output);
350 SatisfyRead(OK, output); 384
385 // Store decoded output.
386 ready_outputs_.push_back(output);
387 scoped_refptr<Output> extra_output;
388 while ((extra_output = decoder_->GetDecodeOutput()) != NULL) {
389 ready_outputs_.push_back(extra_output);
390 }
391
392 // Satisfy outstanding read request, if any.
393 if (!read_cb_.is_null()) {
394 scoped_refptr<Output> read_result = ready_outputs_.front();
395 ready_outputs_.pop_front();
396 SatisfyRead(OK, output);
397 }
351 } 398 }
352 399
353 template <DemuxerStream::Type StreamType> 400 template <DemuxerStream::Type StreamType>
354 void DecoderStream<StreamType>::ReadFromDemuxerStream() { 401 void DecoderStream<StreamType>::ReadFromDemuxerStream() {
355 FUNCTION_DVLOG(2); 402 FUNCTION_DVLOG(2);
356 DCHECK_EQ(state_, STATE_NORMAL) << state_; 403 DCHECK_EQ(state_, STATE_NORMAL) << state_;
357 DCHECK(!read_cb_.is_null()); 404 DCHECK(CanDecodeMore());
358 DCHECK(reset_cb_.is_null()); 405 DCHECK(reset_cb_.is_null());
359 DCHECK(stop_cb_.is_null()); 406 DCHECK(stop_cb_.is_null());
360 407
361 state_ = STATE_PENDING_DEMUXER_READ; 408 state_ = STATE_PENDING_DEMUXER_READ;
362 stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady, 409 stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady,
363 weak_factory_.GetWeakPtr())); 410 weak_factory_.GetWeakPtr()));
364 } 411 }
365 412
366 template <DemuxerStream::Type StreamType> 413 template <DemuxerStream::Type StreamType>
367 void DecoderStream<StreamType>::OnBufferReady( 414 void DecoderStream<StreamType>::OnBufferReady(
368 DemuxerStream::Status status, 415 DemuxerStream::Status status,
369 const scoped_refptr<DecoderBuffer>& buffer) { 416 const scoped_refptr<DecoderBuffer>& buffer) {
370 FUNCTION_DVLOG(2) << ": " << status; 417 FUNCTION_DVLOG(2) << ": " << status;
371 DCHECK(task_runner_->BelongsToCurrentThread()); 418 DCHECK(task_runner_->BelongsToCurrentThread());
372 DCHECK_EQ(state_, STATE_PENDING_DEMUXER_READ) << state_; 419 DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR ||
420 state_ == STATE_STOPPED)
421 << state_;
373 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status; 422 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status;
374 DCHECK(!read_cb_.is_null());
375 DCHECK(stop_cb_.is_null()); 423 DCHECK(stop_cb_.is_null());
376 424
425 // Decoding has been stopped (e.g due to an error).
426 if (state_ != STATE_PENDING_DEMUXER_READ) {
427 DCHECK(state_ == STATE_ERROR || state_ == STATE_STOPPED);
428 DCHECK(read_cb_.is_null());
429 return;
430 }
431
377 state_ = STATE_NORMAL; 432 state_ = STATE_NORMAL;
378 433
379 if (status == DemuxerStream::kConfigChanged) { 434 if (status == DemuxerStream::kConfigChanged) {
380 FUNCTION_DVLOG(2) << ": " << "ConfigChanged"; 435 FUNCTION_DVLOG(2) << ": " << "ConfigChanged";
381 DCHECK(stream_->SupportsConfigChanges()); 436 DCHECK(stream_->SupportsConfigChanges());
382 437
383 if (!config_change_observer_cb_.is_null()) 438 if (!config_change_observer_cb_.is_null())
384 config_change_observer_cb_.Run(); 439 config_change_observer_cb_.Run();
385 440
386 state_ = STATE_FLUSHING_DECODER; 441 state_ = STATE_FLUSHING_DECODER;
387 if (!reset_cb_.is_null()) { 442 if (!reset_cb_.is_null()) {
388 AbortRead();
389 // If we are using DecryptingDemuxerStream, we already called DDS::Reset() 443 // If we are using DecryptingDemuxerStream, we already called DDS::Reset()
390 // which will continue the resetting process in it's callback. 444 // which will continue the resetting process in it's callback.
391 if (!decrypting_demuxer_stream_) 445 if (!decrypting_demuxer_stream_)
392 Reset(base::ResetAndReturn(&reset_cb_)); 446 Reset(base::ResetAndReturn(&reset_cb_));
393 // Reinitialization will continue after Reset() is done. 447 // Reinitialization will continue after Reset() is done.
394 } else { 448 } else {
395 FlushDecoder(); 449 FlushDecoder();
396 } 450 }
397 return; 451 return;
398 } 452 }
399 453
400 if (!reset_cb_.is_null()) { 454 if (!reset_cb_.is_null()) {
401 AbortRead();
402 // If we are using DecryptingDemuxerStream, we already called DDS::Reset() 455 // If we are using DecryptingDemuxerStream, we already called DDS::Reset()
403 // which will continue the resetting process in it's callback. 456 // which will continue the resetting process in it's callback.
404 if (!decrypting_demuxer_stream_) 457 if (!decrypting_demuxer_stream_)
405 Reset(base::ResetAndReturn(&reset_cb_)); 458 Reset(base::ResetAndReturn(&reset_cb_));
406 return; 459 return;
407 } 460 }
408 461
409 if (status == DemuxerStream::kAborted) { 462 if (status == DemuxerStream::kAborted) {
410 SatisfyRead(DEMUXER_READ_ABORTED, NULL); 463 SatisfyRead(DEMUXER_READ_ABORTED, NULL);
411 return; 464 return;
412 } 465 }
413 466
414 if (!splice_observer_cb_.is_null() && !buffer->end_of_stream()) { 467 if (!splice_observer_cb_.is_null() && !buffer->end_of_stream()) {
415 const bool has_splice_ts = buffer->splice_timestamp() != kNoTimestamp(); 468 const bool has_splice_ts = buffer->splice_timestamp() != kNoTimestamp();
416 if (active_splice_ || has_splice_ts) { 469 if (active_splice_ || has_splice_ts) {
417 splice_observer_cb_.Run(buffer->splice_timestamp()); 470 splice_observer_cb_.Run(buffer->splice_timestamp());
418 active_splice_ = has_splice_ts; 471 active_splice_ = has_splice_ts;
419 } 472 }
420 } 473 }
421 474
422 DCHECK(status == DemuxerStream::kOk) << status; 475 DCHECK(status == DemuxerStream::kOk) << status;
423 Decode(buffer); 476 Decode(buffer);
477
478 // Read more data if the decoder supports multiple parallel decoding requests.
479 if (CanDecodeMore() && !buffer->end_of_stream())
480 ReadFromDemuxerStream();
424 } 481 }
425 482
426 template <DemuxerStream::Type StreamType> 483 template <DemuxerStream::Type StreamType>
427 void DecoderStream<StreamType>::ReinitializeDecoder() { 484 void DecoderStream<StreamType>::ReinitializeDecoder() {
428 FUNCTION_DVLOG(2); 485 FUNCTION_DVLOG(2);
429 DCHECK(task_runner_->BelongsToCurrentThread()); 486 DCHECK(task_runner_->BelongsToCurrentThread());
430 DCHECK_EQ(state_, STATE_FLUSHING_DECODER) << state_; 487 DCHECK_EQ(state_, STATE_FLUSHING_DECODER) << state_;
488 DCHECK_EQ(pending_decode_requests_, 0);
431 489
432 DCHECK(StreamTraits::GetDecoderConfig(*stream_).IsValidConfig()); 490 DCHECK(StreamTraits::GetDecoderConfig(*stream_).IsValidConfig());
433 state_ = STATE_REINITIALIZING_DECODER; 491 state_ = STATE_REINITIALIZING_DECODER;
434 DecoderStreamTraits<StreamType>::Initialize( 492 DecoderStreamTraits<StreamType>::Initialize(
435 decoder_.get(), 493 decoder_.get(),
436 StreamTraits::GetDecoderConfig(*stream_), 494 StreamTraits::GetDecoderConfig(*stream_),
437 low_delay_, 495 low_delay_,
438 base::Bind(&DecoderStream<StreamType>::OnDecoderReinitialized, 496 base::Bind(&DecoderStream<StreamType>::OnDecoderReinitialized,
439 weak_factory_.GetWeakPtr())); 497 weak_factory_.GetWeakPtr()));
440 } 498 }
441 499
442 template <DemuxerStream::Type StreamType> 500 template <DemuxerStream::Type StreamType>
443 void DecoderStream<StreamType>::OnDecoderReinitialized(PipelineStatus status) { 501 void DecoderStream<StreamType>::OnDecoderReinitialized(PipelineStatus status) {
444 FUNCTION_DVLOG(2); 502 FUNCTION_DVLOG(2);
445 DCHECK(task_runner_->BelongsToCurrentThread()); 503 DCHECK(task_runner_->BelongsToCurrentThread());
446 DCHECK_EQ(state_, STATE_REINITIALIZING_DECODER) << state_; 504 DCHECK_EQ(state_, STATE_REINITIALIZING_DECODER) << state_;
447 DCHECK(stop_cb_.is_null()); 505 DCHECK(stop_cb_.is_null());
448 506
449 // ReinitializeDecoder() can be called in two cases: 507 // ReinitializeDecoder() can be called in two cases:
450 // 1, Flushing decoder finished (see OnDecodeOutputReady()). 508 // 1, Flushing decoder finished (see OnDecodeOutputReady()).
451 // 2, Reset() was called during flushing decoder (see OnDecoderReset()). 509 // 2, Reset() was called during flushing decoder (see OnDecoderReset()).
452 // Also, Reset() can be called during pending ReinitializeDecoder(). 510 // Also, Reset() can be called during pending ReinitializeDecoder().
453 // This function needs to handle them all! 511 // This function needs to handle them all!
454 512
455 state_ = (status == PIPELINE_OK) ? STATE_NORMAL : STATE_ERROR; 513 state_ = (status == PIPELINE_OK) ? STATE_NORMAL : STATE_ERROR;
456 514
457 if (!reset_cb_.is_null()) { 515 if (!reset_cb_.is_null()) {
458 if (!read_cb_.is_null())
459 AbortRead();
460 base::ResetAndReturn(&reset_cb_).Run(); 516 base::ResetAndReturn(&reset_cb_).Run();
517 return;
461 } 518 }
462 519
463 if (read_cb_.is_null()) 520 if (read_cb_.is_null())
464 return; 521 return;
465 522
466 if (state_ == STATE_ERROR) { 523 if (state_ == STATE_ERROR) {
467 SatisfyRead(DECODE_ERROR, NULL); 524 SatisfyRead(DECODE_ERROR, NULL);
468 return; 525 return;
469 } 526 }
470 527
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 decrypting_demuxer_stream_.reset(); 575 decrypting_demuxer_stream_.reset();
519 // Post |stop_cb_| because pending |read_cb_| and/or |reset_cb_| are also 576 // Post |stop_cb_| because pending |read_cb_| and/or |reset_cb_| are also
520 // posted in Stop(). 577 // posted in Stop().
521 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_)); 578 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_));
522 } 579 }
523 580
524 template class DecoderStream<DemuxerStream::VIDEO>; 581 template class DecoderStream<DemuxerStream::VIDEO>;
525 template class DecoderStream<DemuxerStream::AUDIO>; 582 template class DecoderStream<DemuxerStream::AUDIO>;
526 583
527 } // namespace media 584 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/decoder_stream.h ('k') | media/filters/fake_demuxer_stream.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698