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

Unified Diff: media/filters/decoder_stream.cc

Issue 1939993002: Ignore calls to Reset() when in error state (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/filters/decoder_stream.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/filters/decoder_stream.cc
diff --git a/media/filters/decoder_stream.cc b/media/filters/decoder_stream.cc
index e8f590cf9627c66222c27f9de13f220b593c9e07..039b2b95f2276517e89902fc4815227d040b6cd4 100644
--- a/media/filters/decoder_stream.cc
+++ b/media/filters/decoder_stream.cc
@@ -59,6 +59,8 @@ DecoderStream<StreamType>::DecoderStream(
decoding_eos_(false),
pending_decode_requests_(0),
duration_tracker_(8),
+ received_config_change_during_reinit_(false),
+ pending_demuxer_read_(false),
weak_factory_(this),
fallback_weak_factory_(this) {}
@@ -157,30 +159,43 @@ void DecoderStream<StreamType>::Reset(const base::Closure& closure) {
reset_cb_ = closure;
if (!read_cb_.is_null()) {
- task_runner_->PostTask(FROM_HERE, base::Bind(
- base::ResetAndReturn(&read_cb_), ABORTED, scoped_refptr<Output>()));
+ task_runner_->PostTask(FROM_HERE,
+ base::Bind(base::ResetAndReturn(&read_cb_), ABORTED,
+ scoped_refptr<Output>()));
}
ready_outputs_.clear();
+ // It's possible to have received a DECODE_ERROR and entered STATE_ERROR right
+ // before a Reset() is executed. If we are still waiting for a demuxer read,
+ // OnBufferReady() will handle the reset callback.
+ // See crbug.com/597605 and crbug.com/607454.
+ if (state_ == STATE_ERROR && !pending_demuxer_read_) {
+ task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&reset_cb_));
+ return;
+ }
+
// During decoder reinitialization, the Decoder does not need to be and
// cannot be Reset(). |decrypting_demuxer_stream_| was reset before decoder
// reinitialization.
if (state_ == STATE_REINITIALIZING_DECODER)
return;
- // During pending demuxer read and when not using DecryptingDemuxerStream,
- // the Decoder will be reset after demuxer read is returned
- // (in OnBufferReady()).
- if (state_ == STATE_PENDING_DEMUXER_READ && !decrypting_demuxer_stream_)
- return;
-
+ // |decrypting_demuxer_stream_| will fire all of its read requests when
+ // it resets. |reset_cb_| will be fired in OnDecoderReset(), after the
+ // decrypting demuxer stream finishes its reset.
if (decrypting_demuxer_stream_) {
decrypting_demuxer_stream_->Reset(base::Bind(
&DecoderStream<StreamType>::ResetDecoder, weak_factory_.GetWeakPtr()));
return;
}
+ // During pending demuxer read and when not using DecryptingDemuxerStream,
+ // the Decoder will be reset after demuxer read is returned
+ // (in OnBufferReady()).
+ if (pending_demuxer_read_)
+ return;
+
ResetDecoder();
}
@@ -246,9 +261,7 @@ void DecoderStream<StreamType>::OnDecoderSelected(
<< (selected_decoder ? selected_decoder->GetDisplayName()
: "No decoder selected.");
DCHECK(task_runner_->BelongsToCurrentThread());
- DCHECK(state_ == STATE_INITIALIZING ||
- state_ == STATE_REINITIALIZING_DECODER ||
- state_ == STATE_CONFIG_CHANGE_RECEIVED_WHILE_REINITIALIZING_DECODER)
+ DCHECK(state_ == STATE_INITIALIZING || state_ == STATE_REINITIALIZING_DECODER)
<< state_;
if (state_ == STATE_INITIALIZING) {
DCHECK(!init_cb_.is_null());
@@ -267,7 +280,7 @@ void DecoderStream<StreamType>::OnDecoderSelected(
}
// TODO(tguilbert): crbug.com/603713 support config changes on decoder reinit.
- if (state_ == STATE_CONFIG_CHANGE_RECEIVED_WHILE_REINITIALIZING_DECODER) {
+ if (received_config_change_during_reinit_) {
CompleteDecoderReinitialization(false);
return;
}
@@ -506,6 +519,11 @@ void DecoderStream<StreamType>::ReadFromDemuxerStream() {
return;
}
+ // Set a flag in addition to the state, because the state can be overwritten
+ // when encountering an error. See crbug.com/597605.
+ DCHECK(!pending_demuxer_read_);
+ pending_demuxer_read_ = true;
+
state_ = STATE_PENDING_DEMUXER_READ;
stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady,
weak_factory_.GetWeakPtr()));
@@ -530,6 +548,10 @@ void DecoderStream<StreamType>::OnBufferReady(
}
DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status;
+ // Unset the flag. STATE_PENDING_DEMUXER_READ might have been overwritten.
+ // See crbug.com/597605.
+ pending_demuxer_read_ = false;
+
// If parallel decode requests are supported, multiple read requests might
// have been sent to the demuxer. The buffers might arrive while the decoder
// is reinitializing after falling back on first decode error.
@@ -547,7 +569,7 @@ void DecoderStream<StreamType>::OnBufferReady(
// |decoder_| might have a stale config by the time it is reinitialized.
// Ideally, we would save the config from |stream_| and reinitialize the
// decoder by playing back the sequence of buffers and config changes.
- state_ = STATE_CONFIG_CHANGE_RECEIVED_WHILE_REINITIALIZING_DECODER;
+ received_config_change_during_reinit_ = true;
pending_buffers_.clear();
break;
case DemuxerStream::kAborted:
@@ -563,6 +585,13 @@ void DecoderStream<StreamType>::OnBufferReady(
if (state_ != STATE_PENDING_DEMUXER_READ) {
DCHECK(state_ == STATE_ERROR);
DCHECK(read_cb_.is_null());
+
+ if (!reset_cb_.is_null()) {
+ // If we are using DecryptingDemuxerStream, we already called DDS::Reset()
+ // which will continue the resetting process in its callback.
+ if (!decrypting_demuxer_stream_)
+ Reset(base::ResetAndReturn(&reset_cb_));
+ }
return;
}
@@ -598,7 +627,7 @@ void DecoderStream<StreamType>::OnBufferReady(
state_ = STATE_FLUSHING_DECODER;
if (!reset_cb_.is_null()) {
// If we are using DecryptingDemuxerStream, we already called DDS::Reset()
- // which will continue the resetting process in it's callback.
+ // which will continue the resetting process in its callback.
if (!decrypting_demuxer_stream_)
Reset(base::ResetAndReturn(&reset_cb_));
// Reinitialization will continue after Reset() is done.
@@ -610,7 +639,7 @@ void DecoderStream<StreamType>::OnBufferReady(
if (!reset_cb_.is_null()) {
// If we are using DecryptingDemuxerStream, we already called DDS::Reset()
- // which will continue the resetting process in it's callback.
+ // which will continue the resetting process in its callback.
if (!decrypting_demuxer_stream_)
Reset(base::ResetAndReturn(&reset_cb_));
return;
« 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