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