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, |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 236 } | 237 } |
| 237 | 238 |
| 238 template <DemuxerStream::Type StreamType> | 239 template <DemuxerStream::Type StreamType> |
| 239 void DecoderStream<StreamType>::OnDecoderSelected( | 240 void DecoderStream<StreamType>::OnDecoderSelected( |
| 240 scoped_ptr<Decoder> selected_decoder, | 241 scoped_ptr<Decoder> selected_decoder, |
| 241 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) { | 242 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) { |
| 242 FUNCTION_DVLOG(2) << ": " | 243 FUNCTION_DVLOG(2) << ": " |
| 243 << (selected_decoder ? selected_decoder->GetDisplayName() | 244 << (selected_decoder ? selected_decoder->GetDisplayName() |
| 244 : "No decoder selected."); | 245 : "No decoder selected."); |
| 245 DCHECK(task_runner_->BelongsToCurrentThread()); | 246 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 246 DCHECK(state_ == STATE_INITIALIZING || state_ == STATE_REINITIALIZING_DECODER) | 247 DCHECK(state_ == STATE_INITIALIZING || |
| 248 state_ == STATE_REINITIALIZING_DECODER || | |
| 249 state_ == STATE_CONFIG_CHANGE_RECEIVED_WHILE_REINITIALIZING_DECODER) | |
| 247 << state_; | 250 << state_; |
| 248 if (state_ == STATE_INITIALIZING) { | 251 if (state_ == STATE_INITIALIZING) { |
| 249 DCHECK(!init_cb_.is_null()); | 252 DCHECK(!init_cb_.is_null()); |
| 250 DCHECK(read_cb_.is_null()); | 253 DCHECK(read_cb_.is_null()); |
| 251 DCHECK(reset_cb_.is_null()); | 254 DCHECK(reset_cb_.is_null()); |
| 252 } else { | 255 } else if (state_ == STATE_REINITIALIZING_DECODER) { |
| 253 DCHECK(decoder_); | 256 DCHECK(decoder_); |
| 254 } | 257 } |
| 255 | 258 |
| 256 previous_decoder_ = std::move(decoder_); | 259 previous_decoder_ = std::move(decoder_); |
| 257 decoded_frames_since_fallback_ = 0; | 260 decoded_frames_since_fallback_ = 0; |
| 258 decoder_ = std::move(selected_decoder); | 261 decoder_ = std::move(selected_decoder); |
| 259 if (decrypting_demuxer_stream) { | 262 if (decrypting_demuxer_stream) { |
| 260 decrypting_demuxer_stream_ = std::move(decrypting_demuxer_stream); | 263 decrypting_demuxer_stream_ = std::move(decrypting_demuxer_stream); |
| 261 stream_ = decrypting_demuxer_stream_.get(); | 264 stream_ = decrypting_demuxer_stream_.get(); |
| 262 } | 265 } |
| 263 | 266 |
| 267 // TODO(tguilbert): crbug.com/603713 support config changes on decoder reinit. | |
| 268 if (state_ == STATE_CONFIG_CHANGE_RECEIVED_WHILE_REINITIALIZING_DECODER) { | |
| 269 CompleteDecoderReinitialization(false); | |
| 270 return; | |
| 271 } | |
| 272 | |
| 273 // Attempt to decode buffers from previous decoders (when those decoders have | |
| 274 // never successfully outputed a frame). | |
| 275 fallback_buffers_ = pending_buffers_; | |
| 276 | |
| 264 if (!decoder_) { | 277 if (!decoder_) { |
| 265 if (state_ == STATE_INITIALIZING) { | 278 if (state_ == STATE_INITIALIZING) { |
| 266 state_ = STATE_UNINITIALIZED; | 279 state_ = STATE_UNINITIALIZED; |
| 267 MEDIA_LOG(ERROR, media_log_) << GetStreamTypeString() | 280 MEDIA_LOG(ERROR, media_log_) << GetStreamTypeString() |
| 268 << " decoder initialization failed"; | 281 << " decoder initialization failed"; |
| 269 base::ResetAndReturn(&init_cb_).Run(false); | 282 base::ResetAndReturn(&init_cb_).Run(false); |
| 270 } else { | 283 } else { |
| 271 CompleteDecoderReinitialization(false); | 284 CompleteDecoderReinitialization(false); |
| 272 } | 285 } |
| 273 return; | 286 return; |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 295 Status status, | 308 Status status, |
| 296 const scoped_refptr<Output>& output) { | 309 const scoped_refptr<Output>& output) { |
| 297 DCHECK(!read_cb_.is_null()); | 310 DCHECK(!read_cb_.is_null()); |
| 298 base::ResetAndReturn(&read_cb_).Run(status, output); | 311 base::ResetAndReturn(&read_cb_).Run(status, output); |
| 299 } | 312 } |
| 300 | 313 |
| 301 template <DemuxerStream::Type StreamType> | 314 template <DemuxerStream::Type StreamType> |
| 302 void DecoderStream<StreamType>::Decode( | 315 void DecoderStream<StreamType>::Decode( |
| 303 const scoped_refptr<DecoderBuffer>& buffer) { | 316 const scoped_refptr<DecoderBuffer>& buffer) { |
| 304 FUNCTION_DVLOG(2); | 317 FUNCTION_DVLOG(2); |
| 318 | |
| 319 // We don't know if the decoder will error out on first decode yet. Save the | |
| 320 // buffer to feed it to the fallback decoder later if needed. | |
| 321 if (!decoded_frames_since_fallback_) | |
| 322 pending_buffers_.push_back(buffer); | |
| 323 | |
| 324 DecodeInternal(buffer); | |
| 325 } | |
| 326 | |
| 327 template <DemuxerStream::Type StreamType> | |
| 328 void DecoderStream<StreamType>::DecodeInternal( | |
| 329 const scoped_refptr<DecoderBuffer>& buffer) { | |
| 330 FUNCTION_DVLOG(2); | |
| 305 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_; | 331 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_; |
| 306 DCHECK_LT(pending_decode_requests_, GetMaxDecodeRequests()); | 332 DCHECK_LT(pending_decode_requests_, GetMaxDecodeRequests()); |
| 307 DCHECK(reset_cb_.is_null()); | 333 DCHECK(reset_cb_.is_null()); |
| 308 DCHECK(buffer.get()); | 334 DCHECK(buffer.get()); |
| 309 | 335 |
| 310 int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size(); | 336 int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size(); |
| 311 | 337 |
| 312 TRACE_EVENT_ASYNC_BEGIN2( | 338 TRACE_EVENT_ASYNC_BEGIN2( |
| 313 "media", GetTraceString<StreamType>(), this, "key frame", | 339 "media", GetTraceString<StreamType>(), this, "key frame", |
| 314 !buffer->end_of_stream() && buffer->is_key_frame(), "timestamp (ms)", | 340 !buffer->end_of_stream() && buffer->is_key_frame(), "timestamp (ms)", |
| 315 !buffer->end_of_stream() ? buffer->timestamp().InMilliseconds() : 0); | 341 !buffer->end_of_stream() ? buffer->timestamp().InMilliseconds() : 0); |
| 316 | 342 |
| 317 if (buffer->end_of_stream()) | 343 if (buffer->end_of_stream()) |
| 318 decoding_eos_ = true; | 344 decoding_eos_ = true; |
| 319 else if (buffer->duration() != kNoTimestamp()) | 345 else if (buffer->duration() != kNoTimestamp()) |
| 320 duration_tracker_.AddSample(buffer->duration()); | 346 duration_tracker_.AddSample(buffer->duration()); |
| 321 | 347 |
| 322 ++pending_decode_requests_; | 348 ++pending_decode_requests_; |
| 323 decoder_->Decode(buffer, | 349 decoder_->Decode(buffer, base::Bind(&DecoderStream<StreamType>::OnDecodeDone, |
| 324 base::Bind(&DecoderStream<StreamType>::OnDecodeDone, | 350 decode_weak_factory_.GetWeakPtr(), |
| 325 weak_factory_.GetWeakPtr(), | 351 buffer_size, buffer->end_of_stream())); |
| 326 buffer_size, | |
| 327 buffer->end_of_stream())); | |
| 328 } | 352 } |
| 329 | 353 |
| 330 template <DemuxerStream::Type StreamType> | 354 template <DemuxerStream::Type StreamType> |
| 331 void DecoderStream<StreamType>::FlushDecoder() { | 355 void DecoderStream<StreamType>::FlushDecoder() { |
| 332 Decode(DecoderBuffer::CreateEOSBuffer()); | 356 Decode(DecoderBuffer::CreateEOSBuffer()); |
| 333 } | 357 } |
| 334 | 358 |
| 335 template <DemuxerStream::Type StreamType> | 359 template <DemuxerStream::Type StreamType> |
| 336 void DecoderStream<StreamType>::OnDecodeDone(int buffer_size, | 360 void DecoderStream<StreamType>::OnDecodeDone(int buffer_size, |
| 337 bool end_of_stream, | 361 bool end_of_stream, |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 356 return; | 380 return; |
| 357 } | 381 } |
| 358 | 382 |
| 359 // Drop decoding result if Reset() was called during decoding. | 383 // Drop decoding result if Reset() was called during decoding. |
| 360 // The resetting process will be handled when the decoder is reset. | 384 // The resetting process will be handled when the decoder is reset. |
| 361 if (!reset_cb_.is_null()) | 385 if (!reset_cb_.is_null()) |
| 362 return; | 386 return; |
| 363 | 387 |
| 364 switch (status) { | 388 switch (status) { |
| 365 case DecodeStatus::DECODE_ERROR: | 389 case DecodeStatus::DECODE_ERROR: |
| 390 if (!decoded_frames_since_fallback_) { | |
| 391 pending_decode_requests_ = 0; | |
| 392 | |
| 393 // Prevent all pending decode requests from being called back. | |
| 394 decode_weak_factory_.InvalidateWeakPtrs(); | |
| 395 | |
| 396 state_ = STATE_REINITIALIZING_DECODER; | |
| 397 decoder_selector_->SelectDecoder( | |
| 398 stream_, nullptr, | |
| 399 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected, | |
| 400 weak_factory_.GetWeakPtr()), | |
| 401 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, | |
| 402 weak_factory_.GetWeakPtr()), | |
| 403 waiting_for_decryption_key_cb_); | |
| 404 return; | |
| 405 } | |
| 366 state_ = STATE_ERROR; | 406 state_ = STATE_ERROR; |
| 367 MEDIA_LOG(ERROR, media_log_) << GetStreamTypeString() << " decode error"; | 407 MEDIA_LOG(ERROR, media_log_) << GetStreamTypeString() << " decode error"; |
| 368 ready_outputs_.clear(); | 408 ready_outputs_.clear(); |
| 369 if (!read_cb_.is_null()) | 409 if (!read_cb_.is_null()) |
| 370 SatisfyRead(DECODE_ERROR, NULL); | 410 SatisfyRead(DECODE_ERROR, NULL); |
| 371 return; | 411 return; |
| 372 | 412 |
| 373 case DecodeStatus::ABORTED: | 413 case DecodeStatus::ABORTED: |
| 374 // Decoder can return DecodeStatus::ABORTED during Reset() or during | 414 // Decoder can return DecodeStatus::ABORTED during Reset() or during |
| 375 // destruction. | 415 // destruction. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 411 if (state_ == STATE_ERROR) { | 451 if (state_ == STATE_ERROR) { |
| 412 DCHECK(read_cb_.is_null()); | 452 DCHECK(read_cb_.is_null()); |
| 413 return; | 453 return; |
| 414 } | 454 } |
| 415 | 455 |
| 416 // Drop decoding result if Reset() was called during decoding. | 456 // Drop decoding result if Reset() was called during decoding. |
| 417 // The resetting process will be handled when the decoder is reset. | 457 // The resetting process will be handled when the decoder is reset. |
| 418 if (!reset_cb_.is_null()) | 458 if (!reset_cb_.is_null()) |
| 419 return; | 459 return; |
| 420 | 460 |
| 461 ++decoded_frames_since_fallback_; | |
| 462 | |
| 463 // |decoder_| sucessfully decoded a frame. No need to keep buffers for a | |
| 464 // fallback decoder. | |
| 465 // Note: |fallback_buffers_| might still have buffers, and we will keep | |
| 466 // reading from there before requesting new buffers from |stream_|. | |
| 467 pending_buffers_.clear(); | |
| 468 | |
| 421 if (!read_cb_.is_null()) { | 469 if (!read_cb_.is_null()) { |
| 422 // If |ready_outputs_| was non-empty, the read would have already been | 470 // If |ready_outputs_| was non-empty, the read would have already been |
| 423 // satisifed by Read(). | 471 // satisifed by Read(). |
| 424 DCHECK(ready_outputs_.empty()); | 472 DCHECK(ready_outputs_.empty()); |
| 425 SatisfyRead(OK, output); | 473 SatisfyRead(OK, output); |
| 426 return; | 474 return; |
| 427 } | 475 } |
| 428 | 476 |
| 429 // Store decoded output. | 477 // Store decoded output. |
| 430 ready_outputs_.push_back(output); | 478 ready_outputs_.push_back(output); |
| 431 | 479 |
| 432 // Destruct any previous decoder once we've decoded enough frames to ensure | 480 // Destruct any previous decoder once we've decoded enough frames to ensure |
| 433 // that it's no longer in use. | 481 // that it's no longer in use. |
| 434 if (previous_decoder_ && | 482 if (previous_decoder_ && |
| 435 ++decoded_frames_since_fallback_ > limits::kMaxVideoFrames) { | 483 decoded_frames_since_fallback_ > limits::kMaxVideoFrames) { |
| 436 previous_decoder_.reset(); | 484 previous_decoder_.reset(); |
| 437 } | 485 } |
| 438 } | 486 } |
| 439 | 487 |
| 440 template <DemuxerStream::Type StreamType> | 488 template <DemuxerStream::Type StreamType> |
| 441 void DecoderStream<StreamType>::ReadFromDemuxerStream() { | 489 void DecoderStream<StreamType>::ReadFromDemuxerStream() { |
| 442 FUNCTION_DVLOG(2); | 490 FUNCTION_DVLOG(2); |
| 443 DCHECK_EQ(state_, STATE_NORMAL); | 491 DCHECK_EQ(state_, STATE_NORMAL); |
| 444 DCHECK(CanDecodeMore()); | 492 DCHECK(CanDecodeMore()); |
| 445 DCHECK(reset_cb_.is_null()); | 493 DCHECK(reset_cb_.is_null()); |
| 446 | 494 |
| 495 if (!fallback_buffers_.empty()) { | |
| 496 scoped_refptr<DecoderBuffer> buffer = fallback_buffers_.front(); | |
| 497 fallback_buffers_.pop_front(); | |
| 498 | |
| 499 // Decode the buffer without re-appending it to |pending_buffers_|. | |
| 500 DecodeInternal(buffer); | |
| 501 return; | |
| 502 } | |
| 503 | |
| 447 state_ = STATE_PENDING_DEMUXER_READ; | 504 state_ = STATE_PENDING_DEMUXER_READ; |
| 448 stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady, | 505 stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady, |
| 449 weak_factory_.GetWeakPtr())); | 506 weak_factory_.GetWeakPtr())); |
| 450 } | 507 } |
| 451 | 508 |
| 452 template <DemuxerStream::Type StreamType> | 509 template <DemuxerStream::Type StreamType> |
| 453 void DecoderStream<StreamType>::OnBufferReady( | 510 void DecoderStream<StreamType>::OnBufferReady( |
| 454 DemuxerStream::Status status, | 511 DemuxerStream::Status status, |
| 455 const scoped_refptr<DecoderBuffer>& buffer) { | 512 const scoped_refptr<DecoderBuffer>& buffer) { |
| 456 FUNCTION_DVLOG(2) << ": " << status << ", " | 513 FUNCTION_DVLOG(2) << ": " << status << ", " |
| 457 << (buffer.get() ? buffer->AsHumanReadableString() | 514 << (buffer.get() ? buffer->AsHumanReadableString() |
| 458 : "NULL"); | 515 : "NULL"); |
| 459 | 516 |
| 460 DCHECK(task_runner_->BelongsToCurrentThread()); | 517 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 461 DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR) | 518 if (decoded_frames_since_fallback_) { |
| 462 << state_; | 519 DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR) |
| 520 << state_; | |
| 521 } else { | |
| 522 DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR || | |
| 523 STATE_REINITIALIZING_DECODER) | |
| 524 << state_; | |
| 525 } | |
| 463 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status; | 526 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status; |
| 464 | 527 |
| 528 // If parallel decode requests are supported, multiple read requests might | |
| 529 // have been sent to the demuxer. The buffers might arrive while the decoder | |
| 530 // is reinitializing after falling back on first decode error. | |
| 531 if (state_ == STATE_REINITIALIZING_DECODER && | |
| 532 !decoded_frames_since_fallback_) { | |
| 533 switch (status) { | |
| 534 case DemuxerStream::kOk: | |
| 535 // Save valid buffers to be consumed by the new decoder. | |
| 536 // |pending_buffers_| is copied to |fallback_buffers| in | |
| 537 // OnDecoderSelected(). | |
| 538 pending_buffers_.push_back(buffer); | |
| 539 break; | |
| 540 case DemuxerStream::kConfigChanged: | |
| 541 // TODO(tguilbert): crbug.com/603713 | |
| 542 // |decoder_| might have a stale config by the time it is reinitialized. | |
| 543 // Ideally, we would save the config from |stream_| and reinitialize the | |
| 544 // decoder by playing back the sequence of buffers and config changes. | |
| 545 state_ = STATE_CONFIG_CHANGE_RECEIVED_WHILE_REINITIALIZING_DECODER; | |
| 546 pending_buffers_.clear(); | |
| 547 break; | |
| 548 case DemuxerStream::kAborted: | |
| 549 // |this| will read from the demuxer stream again in OnDecoderSelected() | |
| 550 // and receive a kAborted then. | |
| 551 pending_buffers_.clear(); | |
| 552 break; | |
| 553 } | |
| 554 return; | |
| 555 } | |
| 556 | |
| 465 // Decoding has been stopped (e.g due to an error). | 557 // Decoding has been stopped (e.g due to an error). |
| 466 if (state_ != STATE_PENDING_DEMUXER_READ) { | 558 if (state_ != STATE_PENDING_DEMUXER_READ) { |
| 467 DCHECK(state_ == STATE_ERROR); | 559 DCHECK(state_ == STATE_ERROR); |
| 468 DCHECK(read_cb_.is_null()); | 560 DCHECK(read_cb_.is_null()); |
| 469 return; | 561 return; |
| 470 } | 562 } |
| 471 | 563 |
| 472 state_ = STATE_NORMAL; | 564 state_ = STATE_NORMAL; |
| 473 | 565 |
| 474 if (status == DemuxerStream::kConfigChanged) { | 566 if (status == DemuxerStream::kConfigChanged) { |
| 475 FUNCTION_DVLOG(2) << ": " << "ConfigChanged"; | 567 FUNCTION_DVLOG(2) << ": " << "ConfigChanged"; |
| 476 DCHECK(stream_->SupportsConfigChanges()); | 568 DCHECK(stream_->SupportsConfigChanges()); |
| 477 | 569 |
| 570 // Pending buffers might not match the reinitialized decoder's new config | |
| 571 pending_buffers_.clear(); | |
|
sandersd (OOO until July 31)
2016/04/19 21:12:19
If the current decoder fails after this, we should
tguilbert
2016/04/20 01:13:17
After trying to change the above mentioned state t
| |
| 572 | |
| 478 if (!config_change_observer_cb_.is_null()) | 573 if (!config_change_observer_cb_.is_null()) |
| 479 config_change_observer_cb_.Run(); | 574 config_change_observer_cb_.Run(); |
| 480 | 575 |
| 481 state_ = STATE_FLUSHING_DECODER; | 576 state_ = STATE_FLUSHING_DECODER; |
| 482 if (!reset_cb_.is_null()) { | 577 if (!reset_cb_.is_null()) { |
| 483 // If we are using DecryptingDemuxerStream, we already called DDS::Reset() | 578 // If we are using DecryptingDemuxerStream, we already called DDS::Reset() |
| 484 // which will continue the resetting process in it's callback. | 579 // which will continue the resetting process in it's callback. |
| 485 if (!decrypting_demuxer_stream_) | 580 if (!decrypting_demuxer_stream_) |
| 486 Reset(base::ResetAndReturn(&reset_cb_)); | 581 Reset(base::ResetAndReturn(&reset_cb_)); |
| 487 // Reinitialization will continue after Reset() is done. | 582 // Reinitialization will continue after Reset() is done. |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 604 void DecoderStream<StreamType>::OnDecoderReset() { | 699 void DecoderStream<StreamType>::OnDecoderReset() { |
| 605 FUNCTION_DVLOG(2); | 700 FUNCTION_DVLOG(2); |
| 606 DCHECK(task_runner_->BelongsToCurrentThread()); | 701 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 607 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || | 702 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || |
| 608 state_ == STATE_ERROR || state_ == STATE_END_OF_STREAM) << state_; | 703 state_ == STATE_ERROR || state_ == STATE_END_OF_STREAM) << state_; |
| 609 // If Reset() was called during pending read, read callback should be fired | 704 // If Reset() was called during pending read, read callback should be fired |
| 610 // before the reset callback is fired. | 705 // before the reset callback is fired. |
| 611 DCHECK(read_cb_.is_null()); | 706 DCHECK(read_cb_.is_null()); |
| 612 DCHECK(!reset_cb_.is_null()); | 707 DCHECK(!reset_cb_.is_null()); |
| 613 | 708 |
| 709 // Make sure we read directly from the demuxer after a reset. | |
| 710 fallback_buffers_.clear(); | |
| 711 pending_buffers_.clear(); | |
| 712 | |
| 614 if (state_ != STATE_FLUSHING_DECODER) { | 713 if (state_ != STATE_FLUSHING_DECODER) { |
| 615 state_ = STATE_NORMAL; | 714 state_ = STATE_NORMAL; |
| 616 active_splice_ = false; | 715 active_splice_ = false; |
| 617 base::ResetAndReturn(&reset_cb_).Run(); | 716 base::ResetAndReturn(&reset_cb_).Run(); |
| 618 return; | 717 return; |
| 619 } | 718 } |
| 620 | 719 |
| 621 // The resetting process will be continued in OnDecoderReinitialized(). | 720 // The resetting process will be continued in OnDecoderReinitialized(). |
| 622 ReinitializeDecoder(); | 721 ReinitializeDecoder(); |
| 623 } | 722 } |
| 624 | 723 |
| 625 template class DecoderStream<DemuxerStream::VIDEO>; | 724 template class DecoderStream<DemuxerStream::VIDEO>; |
| 626 template class DecoderStream<DemuxerStream::AUDIO>; | 725 template class DecoderStream<DemuxerStream::AUDIO>; |
| 627 | 726 |
| 628 } // namespace media | 727 } // namespace media |
| OLD | NEW |