summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorxhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-25 00:21:43 +0000
committerxhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-25 00:21:43 +0000
commitcebe829f9355fb36a1bc0e0a207c618dfbabe0c2 (patch)
tree6755a1cb9b0ef4dc4724c1a605538fcaf5527986
parentc7abd4296309d21002aebb32edf8333ada4f74db (diff)
downloadchromium_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.h6
-rw-r--r--media/base/mock_filters.h2
-rw-r--r--media/crypto/aes_decryptor.cc2
-rw-r--r--media/crypto/aes_decryptor.h2
-rw-r--r--media/filters/ffmpeg_video_decoder.cc11
-rw-r--r--media/filters/ffmpeg_video_decoder_unittest.cc58
-rw-r--r--webkit/media/crypto/ppapi_decryptor.cc2
-rw-r--r--webkit/media/crypto/ppapi_decryptor.h2
-rw-r--r--webkit/media/crypto/proxy_decryptor.cc4
-rw-r--r--webkit/media/crypto/proxy_decryptor.h2
-rw-r--r--webkit/media/crypto/proxy_decryptor_unittest.cc4
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();