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

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

Issue 1720343002: Attempt decoder fallback when the first decode call fails. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@resume_zero
Patch Set: Created 4 years, 10 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
« no previous file with comments | « media/filters/decoder_stream.h ('k') | no next file » | 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 <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback_helpers.h" 10 #include "base/callback_helpers.h"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 state_(STATE_UNINITIALIZED), 52 state_(STATE_UNINITIALIZED),
53 stream_(NULL), 53 stream_(NULL),
54 decoder_selector_(new DecoderSelector<StreamType>(task_runner, 54 decoder_selector_(new DecoderSelector<StreamType>(task_runner,
55 std::move(decoders), 55 std::move(decoders),
56 media_log)), 56 media_log)),
57 decoded_frames_since_fallback_(0), 57 decoded_frames_since_fallback_(0),
58 active_splice_(false), 58 active_splice_(false),
59 decoding_eos_(false), 59 decoding_eos_(false),
60 pending_decode_requests_(0), 60 pending_decode_requests_(0),
61 duration_tracker_(8), 61 duration_tracker_(8),
62 sequence_token_(0),
62 weak_factory_(this) {} 63 weak_factory_(this) {}
63 64
64 template <DemuxerStream::Type StreamType> 65 template <DemuxerStream::Type StreamType>
65 DecoderStream<StreamType>::~DecoderStream() { 66 DecoderStream<StreamType>::~DecoderStream() {
66 FUNCTION_DVLOG(2); 67 FUNCTION_DVLOG(2);
67 DCHECK(task_runner_->BelongsToCurrentThread()); 68 DCHECK(task_runner_->BelongsToCurrentThread());
68 69
69 decoder_selector_.reset(); 70 decoder_selector_.reset();
70 71
71 if (!init_cb_.is_null()) { 72 if (!init_cb_.is_null()) {
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 DCHECK(state_ == STATE_INITIALIZING || state_ == STATE_REINITIALIZING_DECODER) 247 DCHECK(state_ == STATE_INITIALIZING || state_ == STATE_REINITIALIZING_DECODER)
247 << state_; 248 << state_;
248 if (state_ == STATE_INITIALIZING) { 249 if (state_ == STATE_INITIALIZING) {
249 DCHECK(!init_cb_.is_null()); 250 DCHECK(!init_cb_.is_null());
250 DCHECK(read_cb_.is_null()); 251 DCHECK(read_cb_.is_null());
251 DCHECK(reset_cb_.is_null()); 252 DCHECK(reset_cb_.is_null());
252 } else { 253 } else {
253 DCHECK(decoder_); 254 DCHECK(decoder_);
254 } 255 }
255 256
257 ++sequence_token_;
256 previous_decoder_ = std::move(decoder_); 258 previous_decoder_ = std::move(decoder_);
257 decoded_frames_since_fallback_ = 0; 259 decoded_frames_since_fallback_ = 0;
258 decoder_ = std::move(selected_decoder); 260 decoder_ = std::move(selected_decoder);
259 if (decrypting_demuxer_stream) { 261 if (decrypting_demuxer_stream) {
260 decrypting_demuxer_stream_ = std::move(decrypting_demuxer_stream); 262 decrypting_demuxer_stream_ = std::move(decrypting_demuxer_stream);
261 stream_ = decrypting_demuxer_stream_.get(); 263 stream_ = decrypting_demuxer_stream_.get();
262 } 264 }
263 265
264 if (!decoder_) { 266 if (!decoder_) {
265 if (state_ == STATE_INITIALIZING) { 267 if (state_ == STATE_INITIALIZING) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 TRACE_EVENT_ASYNC_BEGIN2( 314 TRACE_EVENT_ASYNC_BEGIN2(
313 "media", GetTraceString<StreamType>(), this, "key frame", 315 "media", GetTraceString<StreamType>(), this, "key frame",
314 !buffer->end_of_stream() && buffer->is_key_frame(), "timestamp (ms)", 316 !buffer->end_of_stream() && buffer->is_key_frame(), "timestamp (ms)",
315 !buffer->end_of_stream() ? buffer->timestamp().InMilliseconds() : 0); 317 !buffer->end_of_stream() ? buffer->timestamp().InMilliseconds() : 0);
316 318
317 if (buffer->end_of_stream()) 319 if (buffer->end_of_stream())
318 decoding_eos_ = true; 320 decoding_eos_ = true;
319 else if (buffer->duration() != kNoTimestamp()) 321 else if (buffer->duration() != kNoTimestamp())
320 duration_tracker_.AddSample(buffer->duration()); 322 duration_tracker_.AddSample(buffer->duration());
321 323
324 if (!decoded_frames_since_fallback_ && !previous_decoder_)
325 pending_buffers_.push_back(buffer);
326
322 ++pending_decode_requests_; 327 ++pending_decode_requests_;
323 decoder_->Decode(buffer, 328 decoder_->Decode(buffer,
324 base::Bind(&DecoderStream<StreamType>::OnDecodeDone, 329 base::Bind(&DecoderStream<StreamType>::OnDecodeDone,
325 weak_factory_.GetWeakPtr(), 330 weak_factory_.GetWeakPtr(), sequence_token_,
326 buffer_size, 331 buffer_size, buffer->end_of_stream()));
327 buffer->end_of_stream()));
328 } 332 }
329 333
330 template <DemuxerStream::Type StreamType> 334 template <DemuxerStream::Type StreamType>
331 void DecoderStream<StreamType>::FlushDecoder() { 335 void DecoderStream<StreamType>::FlushDecoder() {
332 Decode(DecoderBuffer::CreateEOSBuffer()); 336 Decode(DecoderBuffer::CreateEOSBuffer());
333 } 337 }
334 338
335 template <DemuxerStream::Type StreamType> 339 template <DemuxerStream::Type StreamType>
336 void DecoderStream<StreamType>::OnDecodeDone(int buffer_size, 340 void DecoderStream<StreamType>::OnDecodeDone(int sequence_token,
341 int buffer_size,
337 bool end_of_stream, 342 bool end_of_stream,
338 typename Decoder::Status status) { 343 typename Decoder::Status status) {
339 FUNCTION_DVLOG(2) << ": " << status; 344 FUNCTION_DVLOG(2) << ": " << status;
345 // Ignore stale calls from a previous decoder.
346 if (sequence_token_ != sequence_token)
347 return;
348
340 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || 349 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
341 state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR) 350 state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR)
342 << state_; 351 << state_;
343 DCHECK_GT(pending_decode_requests_, 0); 352 DCHECK_GT(pending_decode_requests_, 0);
344 353
345 --pending_decode_requests_; 354 --pending_decode_requests_;
346 355
347 TRACE_EVENT_ASYNC_END0("media", GetTraceString<StreamType>(), this); 356 TRACE_EVENT_ASYNC_END0("media", GetTraceString<StreamType>(), this);
348 357
349 if (end_of_stream) { 358 if (end_of_stream) {
350 DCHECK(!pending_decode_requests_); 359 DCHECK(!pending_decode_requests_);
351 decoding_eos_ = false; 360 decoding_eos_ = false;
352 } 361 }
353 362
354 if (state_ == STATE_ERROR) { 363 if (state_ == STATE_ERROR) {
355 DCHECK(read_cb_.is_null()); 364 DCHECK(read_cb_.is_null());
356 return; 365 return;
357 } 366 }
358 367
359 // Drop decoding result if Reset() was called during decoding. 368 // Drop decoding result if Reset() was called during decoding.
360 // The resetting process will be handled when the decoder is reset. 369 // The resetting process will be handled when the decoder is reset.
361 if (!reset_cb_.is_null()) 370 if (!reset_cb_.is_null())
362 return; 371 return;
363 372
364 switch (status) { 373 switch (status) {
365 case Decoder::kDecodeError: 374 case Decoder::kDecodeError:
375 if (!decoded_frames_since_fallback_) {
376 pending_decode_requests_ = 0;
377 state_ = STATE_REINITIALIZING_DECODER;
378 decoder_selector_->SelectDecoder(
379 stream_, nullptr,
380 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected,
381 weak_factory_.GetWeakPtr()),
382 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady,
383 weak_factory_.GetWeakPtr()),
384 waiting_for_decryption_key_cb_);
385 return;
386 }
387
366 state_ = STATE_ERROR; 388 state_ = STATE_ERROR;
367 MEDIA_LOG(ERROR, media_log_) << GetStreamTypeString() << " decode error"; 389 MEDIA_LOG(ERROR, media_log_) << GetStreamTypeString() << " decode error";
368 ready_outputs_.clear(); 390 ready_outputs_.clear();
369 if (!read_cb_.is_null()) 391 if (!read_cb_.is_null())
370 SatisfyRead(DECODE_ERROR, NULL); 392 SatisfyRead(DECODE_ERROR, NULL);
371 return; 393 return;
372 394
373 case Decoder::kAborted: 395 case Decoder::kAborted:
374 // Decoder can return kAborted during Reset() or during destruction. 396 // Decoder can return kAborted during Reset() or during destruction.
375 return; 397 return;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 DCHECK(ready_outputs_.empty()); 445 DCHECK(ready_outputs_.empty());
424 SatisfyRead(OK, output); 446 SatisfyRead(OK, output);
425 return; 447 return;
426 } 448 }
427 449
428 // Store decoded output. 450 // Store decoded output.
429 ready_outputs_.push_back(output); 451 ready_outputs_.push_back(output);
430 452
431 // Destruct any previous decoder once we've decoded enough frames to ensure 453 // Destruct any previous decoder once we've decoded enough frames to ensure
432 // that it's no longer in use. 454 // that it's no longer in use.
433 if (previous_decoder_ && 455 if (++decoded_frames_since_fallback_ > limits::kMaxVideoFrames &&
434 ++decoded_frames_since_fallback_ > limits::kMaxVideoFrames) { 456 previous_decoder_) {
435 previous_decoder_.reset(); 457 previous_decoder_.reset();
436 } 458 }
437 } 459 }
438 460
439 template <DemuxerStream::Type StreamType> 461 template <DemuxerStream::Type StreamType>
440 void DecoderStream<StreamType>::ReadFromDemuxerStream() { 462 void DecoderStream<StreamType>::ReadFromDemuxerStream() {
441 FUNCTION_DVLOG(2); 463 FUNCTION_DVLOG(2);
442 DCHECK_EQ(state_, STATE_NORMAL); 464 DCHECK_EQ(state_, STATE_NORMAL);
443 DCHECK(CanDecodeMore()); 465 DCHECK(CanDecodeMore());
444 DCHECK(reset_cb_.is_null()); 466 DCHECK(reset_cb_.is_null());
445 467
468 if (!pending_buffers_.empty() && previous_decoder_) {
469 scoped_refptr<DecoderBuffer> buffer = pending_buffers_.front();
470 pending_buffers_.pop_front();
471 Decode(buffer);
472 return;
473 }
474
446 state_ = STATE_PENDING_DEMUXER_READ; 475 state_ = STATE_PENDING_DEMUXER_READ;
447 stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady, 476 stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady,
448 weak_factory_.GetWeakPtr())); 477 weak_factory_.GetWeakPtr()));
449 } 478 }
450 479
451 template <DemuxerStream::Type StreamType> 480 template <DemuxerStream::Type StreamType>
452 void DecoderStream<StreamType>::OnBufferReady( 481 void DecoderStream<StreamType>::OnBufferReady(
453 DemuxerStream::Status status, 482 DemuxerStream::Status status,
454 const scoped_refptr<DecoderBuffer>& buffer) { 483 const scoped_refptr<DecoderBuffer>& buffer) {
455 FUNCTION_DVLOG(2) << ": " << status << ", " 484 FUNCTION_DVLOG(2) << ": " << status << ", "
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 } 647 }
619 648
620 // The resetting process will be continued in OnDecoderReinitialized(). 649 // The resetting process will be continued in OnDecoderReinitialized().
621 ReinitializeDecoder(); 650 ReinitializeDecoder();
622 } 651 }
623 652
624 template class DecoderStream<DemuxerStream::VIDEO>; 653 template class DecoderStream<DemuxerStream::VIDEO>;
625 template class DecoderStream<DemuxerStream::AUDIO>; 654 template class DecoderStream<DemuxerStream::AUDIO>;
626 655
627 } // namespace media 656 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/decoder_stream.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698