diff options
author | xhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-25 00:21:43 +0000 |
---|---|---|
committer | xhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-25 00:21:43 +0000 |
commit | cebe829f9355fb36a1bc0e0a207c618dfbabe0c2 (patch) | |
tree | 6755a1cb9b0ef4dc4724c1a605538fcaf5527986 | |
parent | c7abd4296309d21002aebb32edf8333ada4f74db (diff) | |
download | chromium_src-cebe829f9355fb36a1bc0e0a207c618dfbabe0c2.zip chromium_src-cebe829f9355fb36a1bc0e0a207c618dfbabe0c2.tar.gz chromium_src-cebe829f9355fb36a1bc0e0a207c618dfbabe0c2.tar.bz2 |
Call Decryptor::Stop() in FFmpegVideoDecoder::Reset().
To avoid freeze when user trying to seek() when a DecrptCB is pending.
It also fix an issue that the stop_cb isn't fired when FFmpegVideoDecoder::Stop() is called when a DecryptCB is pending.
BUG=151708
TEST=added new unittest to catch this
Review URL: https://chromiumcodereview.appspot.com/10964055
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@158457 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | media/base/decryptor.h | 6 | ||||
-rw-r--r-- | media/base/mock_filters.h | 2 | ||||
-rw-r--r-- | media/crypto/aes_decryptor.cc | 2 | ||||
-rw-r--r-- | media/crypto/aes_decryptor.h | 2 | ||||
-rw-r--r-- | media/filters/ffmpeg_video_decoder.cc | 11 | ||||
-rw-r--r-- | media/filters/ffmpeg_video_decoder_unittest.cc | 58 | ||||
-rw-r--r-- | webkit/media/crypto/ppapi_decryptor.cc | 2 | ||||
-rw-r--r-- | webkit/media/crypto/ppapi_decryptor.h | 2 | ||||
-rw-r--r-- | webkit/media/crypto/proxy_decryptor.cc | 4 | ||||
-rw-r--r-- | webkit/media/crypto/proxy_decryptor.h | 2 | ||||
-rw-r--r-- | webkit/media/crypto/proxy_decryptor_unittest.cc | 4 |
11 files changed, 75 insertions, 20 deletions
diff --git a/media/base/decryptor.h b/media/base/decryptor.h index f014406..a222ccd 100644 --- a/media/base/decryptor.h +++ b/media/base/decryptor.h @@ -81,9 +81,9 @@ class MEDIA_EXPORT Decryptor { virtual void Decrypt(const scoped_refptr<DecoderBuffer>& encrypted, const DecryptCB& decrypt_cb) = 0; - // Stops the decryptor and fires any pending DecryptCB immediately with kError - // and NULL buffer. - virtual void Stop() = 0; + // Cancel scheduled decryption operations and fires any pending DecryptCB + // immediately with kError and NULL buffer. + virtual void CancelDecrypt() = 0; private: DISALLOW_COPY_AND_ASSIGN(Decryptor); diff --git a/media/base/mock_filters.h b/media/base/mock_filters.h index ee3498a..be185dc 100644 --- a/media/base/mock_filters.h +++ b/media/base/mock_filters.h @@ -207,7 +207,7 @@ class MockDecryptor : public Decryptor { const std::string& session_id)); MOCK_METHOD2(Decrypt, void(const scoped_refptr<DecoderBuffer>& encrypted, const DecryptCB& decrypt_cb)); - MOCK_METHOD0(Stop, void()); + MOCK_METHOD0(CancelDecrypt, void()); private: DISALLOW_COPY_AND_ASSIGN(MockDecryptor); diff --git a/media/crypto/aes_decryptor.cc b/media/crypto/aes_decryptor.cc index 0fdfa2d..df17333 100644 --- a/media/crypto/aes_decryptor.cc +++ b/media/crypto/aes_decryptor.cc @@ -229,7 +229,7 @@ void AesDecryptor::Decrypt(const scoped_refptr<DecoderBuffer>& encrypted, decrypt_cb.Run(kSuccess, decrypted); } -void AesDecryptor::Stop() { +void AesDecryptor::CancelDecrypt() { } void AesDecryptor::SetKey(const std::string& key_id, diff --git a/media/crypto/aes_decryptor.h b/media/crypto/aes_decryptor.h index 63bff1c..4ea52a6 100644 --- a/media/crypto/aes_decryptor.h +++ b/media/crypto/aes_decryptor.h @@ -50,7 +50,7 @@ class MEDIA_EXPORT AesDecryptor : public Decryptor { // |decrypt_cb|. virtual void Decrypt(const scoped_refptr<DecoderBuffer>& encrypted, const DecryptCB& decrypt_cb) OVERRIDE; - virtual void Stop() OVERRIDE; + virtual void CancelDecrypt() OVERRIDE; private: // TODO(fgalligan): Remove this and change KeyMap to use crypto::SymmetricKey diff --git a/media/filters/ffmpeg_video_decoder.cc b/media/filters/ffmpeg_video_decoder.cc index 097ebb0..f05fa3f 100644 --- a/media/filters/ffmpeg_video_decoder.cc +++ b/media/filters/ffmpeg_video_decoder.cc @@ -179,6 +179,9 @@ void FFmpegVideoDecoder::Reset(const base::Closure& closure) { return; } + if (decryptor_) + decryptor_->CancelDecrypt(); + reset_cb_ = closure; // Defer the reset if a read is pending. @@ -205,7 +208,7 @@ void FFmpegVideoDecoder::Stop(const base::Closure& closure) { } if (decryptor_) - decryptor_->Stop(); + decryptor_->CancelDecrypt(); stop_cb_ = closure; @@ -322,6 +325,12 @@ void FFmpegVideoDecoder::DoBufferDecrypted( DCHECK_NE(state_, kDecodeFinished); DCHECK(!read_cb_.is_null()); + if (!stop_cb_.is_null()) { + base::ResetAndReturn(&read_cb_).Run(kOk, NULL); + DoStop(); + return; + } + if (!reset_cb_.is_null()) { base::ResetAndReturn(&read_cb_).Run(kOk, NULL); DoReset(); diff --git a/media/filters/ffmpeg_video_decoder_unittest.cc b/media/filters/ffmpeg_video_decoder_unittest.cc index 35c7bcb..d97d7a0 100644 --- a/media/filters/ffmpeg_video_decoder_unittest.cc +++ b/media/filters/ffmpeg_video_decoder_unittest.cc @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <deque> #include <string> #include <vector> @@ -64,6 +63,10 @@ ACTION_P2(RunDecryptCB, status, buffer) { arg1.Run(status, buffer); } +ACTION_P3(RunDecryptCB3, decrypt_cb, status, buffer) { + decrypt_cb.Run(status, buffer); +} + class FFmpegVideoDecoderTest : public testing::Test { public: FFmpegVideoDecoderTest() @@ -234,9 +237,6 @@ class FFmpegVideoDecoderTest : public testing::Test { scoped_refptr<DecoderBuffer> corrupt_i_frame_buffer_; scoped_refptr<DecoderBuffer> encrypted_i_frame_buffer_; - // Used for generating timestamped buffers. - std::deque<int64> timestamps_; - private: DISALLOW_COPY_AND_ASSIGN(FFmpegVideoDecoderTest); }; @@ -574,6 +574,30 @@ TEST_F(FFmpegVideoDecoderTest, Reset_DuringPendingRead) { message_loop_.RunAllPending(); } +// Test resetting when there is a pending decrypt on the decryptor. +TEST_F(FFmpegVideoDecoderTest, Reset_DuringPendingDecrypt) { + InitializeWithEncryptedConfig(); + + EXPECT_CALL(*demuxer_, Read(_)) + .WillRepeatedly(ReturnBuffer(encrypted_i_frame_buffer_)); + + Decryptor::DecryptCB decrypt_cb; + EXPECT_CALL(*decryptor_, Decrypt(encrypted_i_frame_buffer_, _)) + .WillOnce(SaveArg<1>(&decrypt_cb)); + + decoder_->Read(read_cb_); + message_loop_.RunAllPending(); + // Make sure the Read() on the decoder triggers a Decrypt() on the decryptor. + EXPECT_FALSE(decrypt_cb.is_null()); + + EXPECT_CALL(*decryptor_, CancelDecrypt()) + .WillOnce(RunDecryptCB3(decrypt_cb, Decryptor::kError, + scoped_refptr<DecoderBuffer>(NULL))); + EXPECT_CALL(*this, FrameReady(VideoDecoder::kOk, IsNull())); + Reset(); + message_loop_.RunAllPending(); +} + // Test stopping when decoder has initialized but not decoded. TEST_F(FFmpegVideoDecoderTest, Stop_Initialized) { Initialize(); @@ -606,8 +630,7 @@ TEST_F(FFmpegVideoDecoderTest, Stop_DuringPendingRead) { decoder_->Read(read_cb_); message_loop_.RunAllPending(); - // Make sure the Read() on the decoder triggers a Read() on - // the demuxer. + // Make sure the Read() on the decoder triggers a Read() on the demuxer. EXPECT_FALSE(read_cb.is_null()); Stop(); @@ -618,6 +641,29 @@ TEST_F(FFmpegVideoDecoderTest, Stop_DuringPendingRead) { message_loop_.RunAllPending(); } +// Test stopping when there is a pending decrypt on the decryptor. +TEST_F(FFmpegVideoDecoderTest, Stop_DuringPendingDecrypt) { + InitializeWithEncryptedConfig(); + + EXPECT_CALL(*demuxer_, Read(_)) + .WillRepeatedly(ReturnBuffer(encrypted_i_frame_buffer_)); + + Decryptor::DecryptCB decrypt_cb; + EXPECT_CALL(*decryptor_, Decrypt(encrypted_i_frame_buffer_, _)) + .WillOnce(SaveArg<1>(&decrypt_cb)); + + decoder_->Read(read_cb_); + message_loop_.RunAllPending(); + // Make sure the Read() on the decoder triggers a Decrypt() on the decryptor. + EXPECT_FALSE(decrypt_cb.is_null()); + + EXPECT_CALL(*decryptor_, CancelDecrypt()) + .WillOnce(RunDecryptCB3(decrypt_cb, Decryptor::kError, + scoped_refptr<DecoderBuffer>(NULL))); + EXPECT_CALL(*this, FrameReady(VideoDecoder::kOk, IsNull())); + Stop(); + message_loop_.RunAllPending(); +} // Test aborted read on the demuxer stream. TEST_F(FFmpegVideoDecoderTest, AbortPendingRead) { diff --git a/webkit/media/crypto/ppapi_decryptor.cc b/webkit/media/crypto/ppapi_decryptor.cc index ec19cc1..38b9ed4 100644 --- a/webkit/media/crypto/ppapi_decryptor.cc +++ b/webkit/media/crypto/ppapi_decryptor.cc @@ -97,7 +97,7 @@ void PpapiDecryptor::Decrypt( decrypt_cb.Run(kError, NULL); } -void PpapiDecryptor::Stop() { +void PpapiDecryptor::CancelDecrypt() { } void PpapiDecryptor::ReportFailureToCallPlugin(const std::string& key_system, diff --git a/webkit/media/crypto/ppapi_decryptor.h b/webkit/media/crypto/ppapi_decryptor.h index 3326481..18181a0 100644 --- a/webkit/media/crypto/ppapi_decryptor.h +++ b/webkit/media/crypto/ppapi_decryptor.h @@ -50,7 +50,7 @@ class PpapiDecryptor : public media::Decryptor { const std::string& session_id) OVERRIDE; virtual void Decrypt(const scoped_refptr<media::DecoderBuffer>& encrypted, const DecryptCB& decrypt_cb) OVERRIDE; - virtual void Stop() OVERRIDE; + virtual void CancelDecrypt() OVERRIDE; private: void ReportFailureToCallPlugin(const std::string& key_system, diff --git a/webkit/media/crypto/proxy_decryptor.cc b/webkit/media/crypto/proxy_decryptor.cc index bdbabbf..ce01925 100644 --- a/webkit/media/crypto/proxy_decryptor.cc +++ b/webkit/media/crypto/proxy_decryptor.cc @@ -166,14 +166,14 @@ void ProxyDecryptor::Decrypt( base::MessageLoopProxy::current(), encrypted, decrypt_cb)); } -void ProxyDecryptor::Stop() { +void ProxyDecryptor::CancelDecrypt() { DVLOG(1) << "Stop()"; std::vector<base::Closure> closures_to_run; { base::AutoLock auto_lock(lock_); if (decryptor_.get()) - decryptor_->Stop(); + decryptor_->CancelDecrypt(); stopped_ = true; std::swap(pending_decrypt_closures_, closures_to_run); } diff --git a/webkit/media/crypto/proxy_decryptor.h b/webkit/media/crypto/proxy_decryptor.h index 4d42ea9..af0d904 100644 --- a/webkit/media/crypto/proxy_decryptor.h +++ b/webkit/media/crypto/proxy_decryptor.h @@ -56,7 +56,7 @@ class ProxyDecryptor : public media::Decryptor { const std::string& session_id) OVERRIDE; virtual void Decrypt(const scoped_refptr<media::DecoderBuffer>& encrypted, const DecryptCB& decrypt_cb) OVERRIDE; - virtual void Stop() OVERRIDE; + virtual void CancelDecrypt() OVERRIDE; private: scoped_ptr<media::Decryptor> CreatePpapiDecryptor( diff --git a/webkit/media/crypto/proxy_decryptor_unittest.cc b/webkit/media/crypto/proxy_decryptor_unittest.cc index 826d861..bc0a0de 100644 --- a/webkit/media/crypto/proxy_decryptor_unittest.cc +++ b/webkit/media/crypto/proxy_decryptor_unittest.cc @@ -214,10 +214,10 @@ TEST_F(ProxyDecryptorTest, StopWhenDecryptionsPending) { AddKey(); // An irrelevant key is added. proxy_decryptor_.Decrypt(encrypted_buffer_, decrypt_cb_); - EXPECT_CALL(*real_decryptor_, Stop()); + EXPECT_CALL(*real_decryptor_, CancelDecrypt()); EXPECT_CALL(*this, BufferDecrypted(Decryptor::kError, null_buffer_)) .Times(3); - proxy_decryptor_.Stop(); + proxy_decryptor_.CancelDecrypt(); message_loop_.PostTask(FROM_HERE, MessageLoop::QuitClosure()); message_loop_.Run(); |