Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 weak_factory_(this) {} | 62 weak_factory_(this), |
| 63 decode_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()) { |
| 72 task_runner_->PostTask(FROM_HERE, | 73 task_runner_->PostTask(FROM_HERE, |
| 73 base::Bind(base::ResetAndReturn(&init_cb_), false)); | 74 base::Bind(base::ResetAndReturn(&init_cb_), false)); |
| 74 } | 75 } |
| 75 if (!read_cb_.is_null()) { | 76 if (!read_cb_.is_null()) { |
| 76 task_runner_->PostTask(FROM_HERE, base::Bind( | 77 task_runner_->PostTask(FROM_HERE, base::Bind( |
| 77 base::ResetAndReturn(&read_cb_), ABORTED, scoped_refptr<Output>())); | 78 base::ResetAndReturn(&read_cb_), ABORTED, scoped_refptr<Output>())); |
| 78 } | 79 } |
| 79 if (!reset_cb_.is_null()) | 80 if (!reset_cb_.is_null()) |
| 80 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&reset_cb_)); | 81 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&reset_cb_)); |
| 81 | 82 |
| 82 stream_ = NULL; | 83 stream_ = NULL; |
| 84 pending_buffers_.clear(); | |
|
sandersd (OOO until July 31)
2016/04/14 23:10:30
You don't actually need to do this, the destructor
tguilbert
2016/04/15 00:29:18
Done.
| |
| 85 fallback_buffers_.clear(); | |
| 83 decoder_.reset(); | 86 decoder_.reset(); |
| 84 decrypting_demuxer_stream_.reset(); | 87 decrypting_demuxer_stream_.reset(); |
| 85 } | 88 } |
| 86 | 89 |
| 87 template <DemuxerStream::Type StreamType> | 90 template <DemuxerStream::Type StreamType> |
| 88 std::string DecoderStream<StreamType>::GetStreamTypeString() { | 91 std::string DecoderStream<StreamType>::GetStreamTypeString() { |
| 89 return DecoderStreamTraits<StreamType>::ToString(); | 92 return DecoderStreamTraits<StreamType>::ToString(); |
| 90 } | 93 } |
| 91 | 94 |
| 92 template <DemuxerStream::Type StreamType> | 95 template <DemuxerStream::Type StreamType> |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 236 } | 239 } |
| 237 | 240 |
| 238 template <DemuxerStream::Type StreamType> | 241 template <DemuxerStream::Type StreamType> |
| 239 void DecoderStream<StreamType>::OnDecoderSelected( | 242 void DecoderStream<StreamType>::OnDecoderSelected( |
| 240 scoped_ptr<Decoder> selected_decoder, | 243 scoped_ptr<Decoder> selected_decoder, |
| 241 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) { | 244 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) { |
| 242 FUNCTION_DVLOG(2) << ": " | 245 FUNCTION_DVLOG(2) << ": " |
| 243 << (selected_decoder ? selected_decoder->GetDisplayName() | 246 << (selected_decoder ? selected_decoder->GetDisplayName() |
| 244 : "No decoder selected."); | 247 : "No decoder selected."); |
| 245 DCHECK(task_runner_->BelongsToCurrentThread()); | 248 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 246 DCHECK(state_ == STATE_INITIALIZING || state_ == STATE_REINITIALIZING_DECODER) | 249 DCHECK(state_ == STATE_INITIALIZING || |
| 250 state_ == STATE_REINITIALIZING_DECODER || | |
| 251 state_ == STATE_CONFIG_CHANGE_RECEIVED_WHILE_REINITIALIZING_DECODER) | |
| 247 << state_; | 252 << state_; |
| 248 if (state_ == STATE_INITIALIZING) { | 253 if (state_ == STATE_INITIALIZING) { |
| 249 DCHECK(!init_cb_.is_null()); | 254 DCHECK(!init_cb_.is_null()); |
| 250 DCHECK(read_cb_.is_null()); | 255 DCHECK(read_cb_.is_null()); |
| 251 DCHECK(reset_cb_.is_null()); | 256 DCHECK(reset_cb_.is_null()); |
| 257 } else if (state_ == STATE_REINITIALIZING_DECODER) { | |
| 258 DCHECK(decoder_); | |
| 259 } | |
| 260 | |
| 261 // TODO(tguilbert): crbug.com/603713 support config changes on decoder reinit. | |
| 262 if (state_ == STATE_CONFIG_CHANGE_RECEIVED_WHILE_REINITIALIZING_DECODER) { | |
| 263 CompleteDecoderReinitialization(false); | |
|
tguilbert
2016/04/14 22:26:42
Sorry, I didn't take into account what should be d
tguilbert
2016/04/15 00:29:18
Done.
| |
| 264 return; | |
| 265 } | |
| 266 | |
| 267 // Push the pending buffers to the front of the fallback buffers | |
| 268 if (fallback_buffers_.empty()) { | |
| 269 fallback_buffers_.swap(pending_buffers_); | |
| 252 } else { | 270 } else { |
| 253 DCHECK(decoder_); | 271 fallback_buffers_.insert(fallback_buffers_.begin(), |
| 272 pending_buffers_.begin(), pending_buffers_.end()); | |
| 273 pending_buffers_.clear(); | |
| 254 } | 274 } |
| 255 | 275 |
| 256 previous_decoder_ = std::move(decoder_); | 276 previous_decoder_ = std::move(decoder_); |
| 257 decoded_frames_since_fallback_ = 0; | 277 decoded_frames_since_fallback_ = 0; |
| 258 decoder_ = std::move(selected_decoder); | 278 decoder_ = std::move(selected_decoder); |
| 259 if (decrypting_demuxer_stream) { | 279 if (decrypting_demuxer_stream) { |
| 260 decrypting_demuxer_stream_ = std::move(decrypting_demuxer_stream); | 280 decrypting_demuxer_stream_ = std::move(decrypting_demuxer_stream); |
| 261 stream_ = decrypting_demuxer_stream_.get(); | 281 stream_ = decrypting_demuxer_stream_.get(); |
| 262 } | 282 } |
| 263 | 283 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 312 TRACE_EVENT_ASYNC_BEGIN2( | 332 TRACE_EVENT_ASYNC_BEGIN2( |
| 313 "media", GetTraceString<StreamType>(), this, "key frame", | 333 "media", GetTraceString<StreamType>(), this, "key frame", |
| 314 !buffer->end_of_stream() && buffer->is_key_frame(), "timestamp (ms)", | 334 !buffer->end_of_stream() && buffer->is_key_frame(), "timestamp (ms)", |
| 315 !buffer->end_of_stream() ? buffer->timestamp().InMilliseconds() : 0); | 335 !buffer->end_of_stream() ? buffer->timestamp().InMilliseconds() : 0); |
| 316 | 336 |
| 317 if (buffer->end_of_stream()) | 337 if (buffer->end_of_stream()) |
| 318 decoding_eos_ = true; | 338 decoding_eos_ = true; |
| 319 else if (buffer->duration() != kNoTimestamp()) | 339 else if (buffer->duration() != kNoTimestamp()) |
| 320 duration_tracker_.AddSample(buffer->duration()); | 340 duration_tracker_.AddSample(buffer->duration()); |
| 321 | 341 |
| 342 // Don't save the buffer if we have successfully decoded a frame or if it's | |
| 343 // the EOS buffer we send to flush the decoder. | |
|
sandersd (OOO until July 31)
2016/04/14 23:10:30
I still think this would be more clear if ReadFrom
tguilbert
2016/04/15 00:29:18
Done. After our offline discussion, I realized you
| |
| 344 if (!decoded_frames_since_fallback_ && | |
| 345 !(state_ == STATE_FLUSHING_DECODER && buffer->end_of_stream())) { | |
| 346 pending_buffers_.push_back(buffer); | |
| 347 } | |
| 348 | |
| 322 ++pending_decode_requests_; | 349 ++pending_decode_requests_; |
| 323 decoder_->Decode(buffer, | 350 decoder_->Decode(buffer, base::Bind(&DecoderStream<StreamType>::OnDecodeDone, |
| 324 base::Bind(&DecoderStream<StreamType>::OnDecodeDone, | 351 decode_weak_factory_.GetWeakPtr(), |
| 325 weak_factory_.GetWeakPtr(), | 352 buffer_size, buffer->end_of_stream())); |
| 326 buffer_size, | |
| 327 buffer->end_of_stream())); | |
| 328 } | 353 } |
| 329 | 354 |
| 330 template <DemuxerStream::Type StreamType> | 355 template <DemuxerStream::Type StreamType> |
| 331 void DecoderStream<StreamType>::FlushDecoder() { | 356 void DecoderStream<StreamType>::FlushDecoder() { |
| 332 Decode(DecoderBuffer::CreateEOSBuffer()); | 357 Decode(DecoderBuffer::CreateEOSBuffer()); |
| 333 } | 358 } |
| 334 | 359 |
| 335 template <DemuxerStream::Type StreamType> | 360 template <DemuxerStream::Type StreamType> |
| 336 void DecoderStream<StreamType>::OnDecodeDone(int buffer_size, | 361 void DecoderStream<StreamType>::OnDecodeDone(int buffer_size, |
| 337 bool end_of_stream, | 362 bool end_of_stream, |
| 338 DecodeStatus status) { | 363 DecodeStatus status) { |
| 339 FUNCTION_DVLOG(2) << ": " << status; | 364 FUNCTION_DVLOG(2) << ": " << status; |
| 365 | |
| 340 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || | 366 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || |
| 341 state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR) | 367 state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR) |
| 342 << state_; | 368 << state_; |
| 343 DCHECK_GT(pending_decode_requests_, 0); | 369 DCHECK_GT(pending_decode_requests_, 0); |
| 344 | 370 |
| 345 --pending_decode_requests_; | 371 --pending_decode_requests_; |
| 346 | 372 |
| 347 TRACE_EVENT_ASYNC_END0("media", GetTraceString<StreamType>(), this); | 373 TRACE_EVENT_ASYNC_END0("media", GetTraceString<StreamType>(), this); |
| 348 | 374 |
| 349 if (end_of_stream) { | 375 if (end_of_stream) { |
| 350 DCHECK(!pending_decode_requests_); | 376 DCHECK(!pending_decode_requests_); |
| 351 decoding_eos_ = false; | 377 decoding_eos_ = false; |
| 352 } | 378 } |
| 353 | 379 |
| 354 if (state_ == STATE_ERROR) { | 380 if (state_ == STATE_ERROR) { |
| 355 DCHECK(read_cb_.is_null()); | 381 DCHECK(read_cb_.is_null()); |
| 356 return; | 382 return; |
| 357 } | 383 } |
| 358 | 384 |
| 359 // Drop decoding result if Reset() was called during decoding. | 385 // Drop decoding result if Reset() was called during decoding. |
| 360 // The resetting process will be handled when the decoder is reset. | 386 // The resetting process will be handled when the decoder is reset. |
| 361 if (!reset_cb_.is_null()) | 387 if (!reset_cb_.is_null()) |
| 362 return; | 388 return; |
| 363 | 389 |
| 364 switch (status) { | 390 switch (status) { |
| 365 case DecodeStatus::DECODE_ERROR: | 391 case DecodeStatus::DECODE_ERROR: |
| 392 if (!decoded_frames_since_fallback_) { | |
| 393 pending_decode_requests_ = 0; | |
| 394 // Prevent all pending decode requests from being called back. | |
|
sandersd (OOO until July 31)
2016/04/14 23:10:30
Newline before comment.
tguilbert
2016/04/15 00:29:18
Done.
| |
| 395 decode_weak_factory_.InvalidateWeakPtrs(); | |
| 396 | |
| 397 state_ = STATE_REINITIALIZING_DECODER; | |
| 398 decoder_selector_->SelectDecoder( | |
| 399 stream_, nullptr, | |
| 400 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected, | |
| 401 weak_factory_.GetWeakPtr()), | |
| 402 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, | |
| 403 weak_factory_.GetWeakPtr()), | |
| 404 waiting_for_decryption_key_cb_); | |
| 405 return; | |
| 406 } | |
| 366 state_ = STATE_ERROR; | 407 state_ = STATE_ERROR; |
| 367 MEDIA_LOG(ERROR, media_log_) << GetStreamTypeString() << " decode error"; | 408 MEDIA_LOG(ERROR, media_log_) << GetStreamTypeString() << " decode error"; |
| 368 ready_outputs_.clear(); | 409 ready_outputs_.clear(); |
| 369 if (!read_cb_.is_null()) | 410 if (!read_cb_.is_null()) |
| 370 SatisfyRead(DECODE_ERROR, NULL); | 411 SatisfyRead(DECODE_ERROR, NULL); |
| 371 return; | 412 return; |
| 372 | 413 |
| 373 case DecodeStatus::ABORTED: | 414 case DecodeStatus::ABORTED: |
| 374 // Decoder can return DecodeStatus::ABORTED during Reset() or during | 415 // Decoder can return DecodeStatus::ABORTED during Reset() or during |
| 375 // destruction. | 416 // destruction. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 411 if (state_ == STATE_ERROR) { | 452 if (state_ == STATE_ERROR) { |
| 412 DCHECK(read_cb_.is_null()); | 453 DCHECK(read_cb_.is_null()); |
| 413 return; | 454 return; |
| 414 } | 455 } |
| 415 | 456 |
| 416 // Drop decoding result if Reset() was called during decoding. | 457 // Drop decoding result if Reset() was called during decoding. |
| 417 // The resetting process will be handled when the decoder is reset. | 458 // The resetting process will be handled when the decoder is reset. |
| 418 if (!reset_cb_.is_null()) | 459 if (!reset_cb_.is_null()) |
| 419 return; | 460 return; |
| 420 | 461 |
| 462 ++decoded_frames_since_fallback_; | |
| 463 | |
| 464 if (!pending_buffers_.empty()) | |
|
sandersd (OOO until July 31)
2016/04/14 23:10:30
No need for a condition, it can just be unconditio
tguilbert
2016/04/15 00:29:18
Oops! Artifact of the previous patchset.
| |
| 465 pending_buffers_.clear(); | |
| 466 | |
| 421 if (!read_cb_.is_null()) { | 467 if (!read_cb_.is_null()) { |
| 422 // If |ready_outputs_| was non-empty, the read would have already been | 468 // If |ready_outputs_| was non-empty, the read would have already been |
| 423 // satisifed by Read(). | 469 // satisifed by Read(). |
| 424 DCHECK(ready_outputs_.empty()); | 470 DCHECK(ready_outputs_.empty()); |
| 425 SatisfyRead(OK, output); | 471 SatisfyRead(OK, output); |
| 426 return; | 472 return; |
| 427 } | 473 } |
| 428 | 474 |
| 429 // Store decoded output. | 475 // Store decoded output. |
| 430 ready_outputs_.push_back(output); | 476 ready_outputs_.push_back(output); |
| 431 | 477 |
| 432 // Destruct any previous decoder once we've decoded enough frames to ensure | 478 // Destruct any previous decoder once we've decoded enough frames to ensure |
| 433 // that it's no longer in use. | 479 // that it's no longer in use. |
| 434 if (previous_decoder_ && | 480 if (previous_decoder_ && |
| 435 ++decoded_frames_since_fallback_ > limits::kMaxVideoFrames) { | 481 decoded_frames_since_fallback_ > limits::kMaxVideoFrames) { |
| 436 previous_decoder_.reset(); | 482 previous_decoder_.reset(); |
| 437 } | 483 } |
| 438 } | 484 } |
| 439 | 485 |
| 440 template <DemuxerStream::Type StreamType> | 486 template <DemuxerStream::Type StreamType> |
| 441 void DecoderStream<StreamType>::ReadFromDemuxerStream() { | 487 void DecoderStream<StreamType>::ReadFromDemuxerStream() { |
| 442 FUNCTION_DVLOG(2); | 488 FUNCTION_DVLOG(2); |
| 443 DCHECK_EQ(state_, STATE_NORMAL); | 489 DCHECK_EQ(state_, STATE_NORMAL); |
| 444 DCHECK(CanDecodeMore()); | 490 DCHECK(CanDecodeMore()); |
| 445 DCHECK(reset_cb_.is_null()); | 491 DCHECK(reset_cb_.is_null()); |
| 446 | 492 |
| 493 if (!fallback_buffers_.empty()) { | |
| 494 scoped_refptr<DecoderBuffer> buffer = fallback_buffers_.front(); | |
| 495 fallback_buffers_.pop_front(); | |
| 496 Decode(buffer); | |
| 497 return; | |
| 498 } | |
| 499 | |
| 447 state_ = STATE_PENDING_DEMUXER_READ; | 500 state_ = STATE_PENDING_DEMUXER_READ; |
| 448 stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady, | 501 stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady, |
| 449 weak_factory_.GetWeakPtr())); | 502 weak_factory_.GetWeakPtr())); |
| 450 } | 503 } |
| 451 | 504 |
| 452 template <DemuxerStream::Type StreamType> | 505 template <DemuxerStream::Type StreamType> |
| 453 void DecoderStream<StreamType>::OnBufferReady( | 506 void DecoderStream<StreamType>::OnBufferReady( |
| 454 DemuxerStream::Status status, | 507 DemuxerStream::Status status, |
| 455 const scoped_refptr<DecoderBuffer>& buffer) { | 508 const scoped_refptr<DecoderBuffer>& buffer) { |
| 456 FUNCTION_DVLOG(2) << ": " << status << ", " | 509 FUNCTION_DVLOG(2) << ": " << status << ", " |
| 457 << (buffer.get() ? buffer->AsHumanReadableString() | 510 << (buffer.get() ? buffer->AsHumanReadableString() |
| 458 : "NULL"); | 511 : "NULL"); |
| 459 | 512 |
| 460 DCHECK(task_runner_->BelongsToCurrentThread()); | 513 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 461 DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR) | 514 if (decoded_frames_since_fallback_) { |
| 462 << state_; | 515 DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR) |
| 516 << state_; | |
| 517 } else { | |
| 518 DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR || | |
| 519 STATE_REINITIALIZING_DECODER) | |
| 520 << state_; | |
| 521 } | |
| 463 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status; | 522 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status; |
| 464 | 523 |
| 524 // If parallel decode requests are supported, multiple read requests might | |
| 525 // have been sent to the demuxer. The buffers might arrive while the decoder | |
| 526 // is reinitializing after falling back on first decode error. | |
| 527 if (state_ == STATE_REINITIALIZING_DECODER && | |
| 528 !decoded_frames_since_fallback_) { | |
| 529 switch (status) { | |
| 530 case DemuxerStream::kOk: | |
| 531 // Save valid buffers to be consumed by the new decoder. | |
| 532 // |pending_buffers_| is copied to |fallback_buffers| in | |
| 533 // OnDecoderSelected(). | |
| 534 pending_buffers_.push_back(buffer); | |
| 535 break; | |
| 536 case DemuxerStream::kConfigChanged: | |
| 537 // TODO(tguilbert): crbug.com/603713 | |
| 538 // |decoder_| might have a stale config by the time it is reinitialized. | |
| 539 // Ideally, we would save the config from |stream_| and reinitialize the | |
| 540 // decoder by playing back the sequence of buffers and config changes. | |
| 541 state_ = STATE_CONFIG_CHANGE_RECEIVED_WHILE_REINITIALIZING_DECODER; | |
| 542 pending_buffers_.clear(); | |
| 543 break; | |
| 544 case DemuxerStream::kAborted: | |
| 545 // |this| will read from the demuxer stream again in OnDecoderSelected() | |
| 546 // and receive a kAborted then. | |
| 547 pending_buffers_.clear(); | |
| 548 break; | |
| 549 default: | |
| 550 NOTREACHED(); | |
| 551 break; | |
| 552 } | |
| 553 return; | |
| 554 } | |
| 555 | |
| 465 // Decoding has been stopped (e.g due to an error). | 556 // Decoding has been stopped (e.g due to an error). |
| 466 if (state_ != STATE_PENDING_DEMUXER_READ) { | 557 if (state_ != STATE_PENDING_DEMUXER_READ) { |
| 467 DCHECK(state_ == STATE_ERROR); | 558 DCHECK(state_ == STATE_ERROR); |
| 468 DCHECK(read_cb_.is_null()); | 559 DCHECK(read_cb_.is_null()); |
| 469 return; | 560 return; |
| 470 } | 561 } |
| 471 | 562 |
| 472 state_ = STATE_NORMAL; | 563 state_ = STATE_NORMAL; |
| 473 | 564 |
| 474 if (status == DemuxerStream::kConfigChanged) { | 565 if (status == DemuxerStream::kConfigChanged) { |
| 475 FUNCTION_DVLOG(2) << ": " << "ConfigChanged"; | 566 FUNCTION_DVLOG(2) << ": " << "ConfigChanged"; |
| 476 DCHECK(stream_->SupportsConfigChanges()); | 567 DCHECK(stream_->SupportsConfigChanges()); |
| 477 | 568 |
| 569 // Pending buffers might not match the reinitialiazed decoder's new config | |
| 570 pending_buffers_.clear(); | |
| 571 | |
| 478 if (!config_change_observer_cb_.is_null()) | 572 if (!config_change_observer_cb_.is_null()) |
| 479 config_change_observer_cb_.Run(); | 573 config_change_observer_cb_.Run(); |
| 480 | 574 |
| 481 state_ = STATE_FLUSHING_DECODER; | 575 state_ = STATE_FLUSHING_DECODER; |
| 482 if (!reset_cb_.is_null()) { | 576 if (!reset_cb_.is_null()) { |
| 483 // If we are using DecryptingDemuxerStream, we already called DDS::Reset() | 577 // If we are using DecryptingDemuxerStream, we already called DDS::Reset() |
| 484 // which will continue the resetting process in it's callback. | 578 // which will continue the resetting process in it's callback. |
| 485 if (!decrypting_demuxer_stream_) | 579 if (!decrypting_demuxer_stream_) |
| 486 Reset(base::ResetAndReturn(&reset_cb_)); | 580 Reset(base::ResetAndReturn(&reset_cb_)); |
| 487 // Reinitialization will continue after Reset() is done. | 581 // Reinitialization will continue after Reset() is done. |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 619 } | 713 } |
| 620 | 714 |
| 621 // The resetting process will be continued in OnDecoderReinitialized(). | 715 // The resetting process will be continued in OnDecoderReinitialized(). |
| 622 ReinitializeDecoder(); | 716 ReinitializeDecoder(); |
| 623 } | 717 } |
| 624 | 718 |
| 625 template class DecoderStream<DemuxerStream::VIDEO>; | 719 template class DecoderStream<DemuxerStream::VIDEO>; |
| 626 template class DecoderStream<DemuxerStream::AUDIO>; | 720 template class DecoderStream<DemuxerStream::AUDIO>; |
| 627 | 721 |
| 628 } // namespace media | 722 } // namespace media |
| OLD | NEW |