Chromium Code Reviews| Index: media/filters/pipeline_integration_test.cc |
| diff --git a/media/filters/pipeline_integration_test.cc b/media/filters/pipeline_integration_test.cc |
| index 96a4e346e2b1ff2222319bbef56ffb8b2eba4729..84c4f0297d901e47e11777467ae1eda08b96724a 100644 |
| --- a/media/filters/pipeline_integration_test.cc |
| +++ b/media/filters/pipeline_integration_test.cc |
| @@ -248,6 +248,59 @@ class KeyProvidingApp : public FakeEncryptedMedia::AppBase { |
| uint32 current_session_id_; |
| }; |
| +class RotatingKeyProvidingApp : public KeyProvidingApp { |
| + public: |
| + virtual void NeedKey(const std::string& type, |
| + const std::vector<uint8>& init_data, |
| + AesDecryptor* decryptor) OVERRIDE { |
| + EXPECT_TRUE(decryptor->CreateSession(current_session_id_ + 1, |
|
xhwang
2014/05/09 04:52:24
It'll be nice to make sure NeedKey is fired multip
kqyang
2014/05/09 21:07:25
Done.
|
| + type, |
| + vector_as_array(&init_data), |
| + init_data.size())); |
| + |
| + std::vector<uint8> key_id; |
| + std::vector<uint8> key; |
| + EXPECT_TRUE(GetKeyAndKeyId(init_data, &key, &key_id)); |
| + |
| + // Convert key into a JSON structure and then add it. |
| + std::string jwk = GenerateJWKSet(vector_as_array(&key), |
| + key.size(), |
| + vector_as_array(&key_id), |
| + key_id.size()); |
| + decryptor->UpdateSession(current_session_id_, |
| + reinterpret_cast<const uint8*>(jwk.data()), |
| + jwk.size()); |
| + } |
| + |
| + private: |
| + bool GetKeyAndKeyId(std::vector<uint8> init_data, |
| + std::vector<uint8>* key, |
| + std::vector<uint8>* key_id) { |
| + // For WebM, init_data is key_id; for ISO CENC, init_data should contain |
| + // the key_id. We assume key_id is in the end of init_data here (that is |
| + // only a reasonable assumption for WebM and clear key ISO CENC). |
| + DCHECK_GE(init_data.size(), arraysize(kKeyId)); |
| + std::vector<uint8> key_id_from_init_data( |
| + init_data.end() - arraysize(kKeyId), init_data.end()); |
| + |
| + // The Key and KeyId for this testing key provider are created by rotating |
| + // kSecretKey and kKeyId. |
| + key->assign(kSecretKey, kSecretKey + arraysize(kSecretKey)); |
| + key_id->assign(kKeyId, kKeyId + arraysize(kKeyId)); |
| + |
| + // Find out the rotating position from |key_id_from_init_data| and apply on |
| + // |key|. |
| + for (size_t pos = 0; pos < arraysize(kKeyId); ++pos) { |
| + std::rotate(key_id->begin(), key_id->begin() + pos, key_id->end()); |
|
xhwang
2014/05/09 04:52:24
This "rotate" and "key rotation" are two different
kqyang
2014/05/09 21:07:25
Done.
|
| + if (*key_id == key_id_from_init_data) { |
| + std::rotate(key->begin(), key->begin() + pos, key->end()); |
| + return true; |
| + } |
| + } |
| + return false; |
| + } |
| +}; |
| + |
| // Ignores needkey and does not perform a license request |
| class NoResponseApp : public FakeEncryptedMedia::AppBase { |
| public: |
| @@ -957,6 +1010,33 @@ TEST_P(PipelineIntegrationTest, |
| Stop(); |
| } |
| +TEST_P(PipelineIntegrationTest, |
| + MediaSource_ConfigChange_Encrypted_MP4_CENC_KeyRotation_VideoOnly) { |
| + MockMediaSource source("bear-640x360-v_frag-cenc-key_rotation.mp4", |
| + kMP4Video, kAppendWholeFile, GetParam()); |
| + FakeEncryptedMedia encrypted_media(new RotatingKeyProvidingApp()); |
| + StartPipelineWithEncryptedMedia(&source, &encrypted_media); |
| + |
| + scoped_refptr<DecoderBuffer> second_file = |
| + ReadTestDataFile("bear-1280x720-v_frag-cenc-key_rotation.mp4"); |
| + |
| + source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec), |
| + second_file->data(), second_file->data_size()); |
| + |
| + source.EndOfStream(); |
| + |
| + EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size()); |
| + EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds()); |
| + EXPECT_EQ(kAppendTimeMs + k1280IsoFileDurationMs, |
| + pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds()); |
| + |
| + Play(); |
| + |
| + EXPECT_TRUE(WaitUntilOnEnded()); |
| + source.Abort(); |
| + Stop(); |
| +} |
| + |
| // Config changes from clear to encrypted are not currently supported. |
| // TODO(ddorwin): Figure out why this CHECKs in AppendAtTime(). |
| TEST_P(PipelineIntegrationTest, |
| @@ -1167,6 +1247,37 @@ TEST_P(PipelineIntegrationTest, BasicPlayback_MediaSource_VideoOnly_MP4_AVC3) { |
| Stop(); |
| } |
| +TEST_P(PipelineIntegrationTest, EncryptedPlayback_MP4_CENC_KeyRotation_Video) { |
| + MockMediaSource source("bear-1280x720-v_frag-cenc-key_rotation.mp4", |
| + kMP4Video, kAppendWholeFile, GetParam()); |
| + FakeEncryptedMedia encrypted_media(new RotatingKeyProvidingApp()); |
| + StartPipelineWithEncryptedMedia(&source, &encrypted_media); |
| + |
| + source.EndOfStream(); |
| + ASSERT_EQ(PIPELINE_OK, pipeline_status_); |
| + |
| + Play(); |
| + |
| + ASSERT_TRUE(WaitUntilOnEnded()); |
| + source.Abort(); |
| + Stop(); |
| +} |
| + |
| +TEST_P(PipelineIntegrationTest, EncryptedPlayback_MP4_CENC_KeyRotation_Audio) { |
| + MockMediaSource source("bear-1280x720-a_frag-cenc-key_rotation.mp4", |
| + kMP4Audio, kAppendWholeFile, GetParam()); |
| + FakeEncryptedMedia encrypted_media(new RotatingKeyProvidingApp()); |
| + StartPipelineWithEncryptedMedia(&source, &encrypted_media); |
| + |
| + source.EndOfStream(); |
| + ASSERT_EQ(PIPELINE_OK, pipeline_status_); |
| + |
| + Play(); |
| + |
| + ASSERT_TRUE(WaitUntilOnEnded()); |
| + source.Abort(); |
| + Stop(); |
| +} |
| #endif |
| // TODO(acolwell): Fix flakiness http://crbug.com/117921 |