OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/pipeline_integration_test_base.h" | 5 #include "media/filters/pipeline_integration_test_base.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "media/base/decoder_buffer.h" | 8 #include "media/base/decoder_buffer.h" |
9 #include "media/base/test_data_util.h" | 9 #include "media/base/test_data_util.h" |
10 #include "media/filters/chunk_demuxer_client.h" | 10 #include "media/filters/chunk_demuxer_client.h" |
11 | 11 |
12 namespace media { | 12 namespace media { |
13 | 13 |
14 // Key ID of the video track in test file "bear-320x240-encrypted.webm". | 14 // Key ID of the video track in test file "bear-320x240-encrypted.webm". |
15 static const unsigned char kKeyId[] = | 15 static const unsigned char kKeyId[] = |
16 "\x11\xa5\x18\x37\xc4\x73\x84\x03\xe5\xe6\x57\xed\x8e\x06\xd9\x7c"; | 16 "\x11\xa5\x18\x37\xc4\x73\x84\x03\xe5\xe6\x57\xed\x8e\x06\xd9\x7c"; |
17 | 17 |
18 static const char* kSourceId = "SourceId"; | 18 static const char* kSourceId = "SourceId"; |
19 | 19 |
20 // Helper class that emulates calls made on the ChunkDemuxer by the | 20 // Helper class that emulates calls made on the ChunkDemuxer by the |
21 // Media Source API. | 21 // Media Source API. |
22 class MockMediaSource : public ChunkDemuxerClient { | 22 class MockMediaSource : public ChunkDemuxerClient { |
23 public: | 23 public: |
24 MockMediaSource(const std::string& filename, int initial_append_size) | 24 MockMediaSource(const std::string& filename, int initial_append_size, |
| 25 bool has_audio, bool has_video) |
25 : url_(GetTestDataURL(filename)), | 26 : url_(GetTestDataURL(filename)), |
26 current_position_(0), | 27 current_position_(0), |
27 initial_append_size_(initial_append_size) { | 28 initial_append_size_(initial_append_size), |
| 29 has_audio_(has_audio), |
| 30 has_video_(has_video) { |
28 file_data_ = ReadTestDataFile(filename); | 31 file_data_ = ReadTestDataFile(filename); |
29 | 32 |
30 DCHECK_GT(initial_append_size_, 0); | 33 DCHECK_GT(initial_append_size_, 0); |
31 DCHECK_LE(initial_append_size_, file_data_->GetDataSize()); | 34 DCHECK_LE(initial_append_size_, file_data_->GetDataSize()); |
32 } | 35 } |
33 | 36 |
34 virtual ~MockMediaSource() {} | 37 virtual ~MockMediaSource() {} |
35 | 38 |
36 void set_decryptor(AesDecryptor* decryptor) { | 39 void set_decryptor(AesDecryptor* decryptor) { |
37 decryptor_ = decryptor; | 40 decryptor_ = decryptor; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 void Abort() { | 73 void Abort() { |
71 if (!chunk_demuxer_.get()) | 74 if (!chunk_demuxer_.get()) |
72 return; | 75 return; |
73 chunk_demuxer_->Shutdown(); | 76 chunk_demuxer_->Shutdown(); |
74 } | 77 } |
75 | 78 |
76 // ChunkDemuxerClient methods. | 79 // ChunkDemuxerClient methods. |
77 virtual void DemuxerOpened(ChunkDemuxer* demuxer) { | 80 virtual void DemuxerOpened(ChunkDemuxer* demuxer) { |
78 chunk_demuxer_ = demuxer; | 81 chunk_demuxer_ = demuxer; |
79 | 82 |
80 std::vector<std::string> codecs(2); | 83 std::vector<std::string> codecs; |
81 codecs[0] = "vp8"; | 84 if (has_audio_) |
82 codecs[1] = "vorbis"; | 85 codecs.push_back("vorbis"); |
| 86 |
| 87 if (has_video_) |
| 88 codecs.push_back("vp8"); |
| 89 |
83 chunk_demuxer_->AddId(kSourceId, "video/webm", codecs); | 90 chunk_demuxer_->AddId(kSourceId, "video/webm", codecs); |
84 AppendData(initial_append_size_); | 91 AppendData(initial_append_size_); |
85 } | 92 } |
86 | 93 |
87 virtual void DemuxerClosed() { | 94 virtual void DemuxerClosed() { |
88 chunk_demuxer_ = NULL; | 95 chunk_demuxer_ = NULL; |
89 } | 96 } |
90 | 97 |
91 virtual void KeyNeeded(scoped_array<uint8> init_data, int init_data_size) { | 98 virtual void KeyNeeded(scoped_array<uint8> init_data, int init_data_size) { |
92 DCHECK(init_data.get()); | 99 DCHECK(init_data.get()); |
93 DCHECK_EQ(init_data_size, 16); | 100 DCHECK_EQ(init_data_size, 16); |
94 DCHECK(decryptor()); | 101 DCHECK(decryptor()); |
95 // In test file bear-320x240-encrypted.webm, the decryption key is equal to | 102 // In test file bear-320x240-encrypted.webm, the decryption key is equal to |
96 // |init_data|. | 103 // |init_data|. |
97 decryptor()->AddKey(init_data.get(), init_data_size, | 104 decryptor()->AddKey(init_data.get(), init_data_size, |
98 init_data.get(), init_data_size); | 105 init_data.get(), init_data_size); |
99 } | 106 } |
100 | 107 |
101 private: | 108 private: |
102 std::string url_; | 109 std::string url_; |
103 scoped_refptr<DecoderBuffer> file_data_; | 110 scoped_refptr<DecoderBuffer> file_data_; |
104 int current_position_; | 111 int current_position_; |
105 int initial_append_size_; | 112 int initial_append_size_; |
| 113 bool has_audio_; |
| 114 bool has_video_; |
106 scoped_refptr<ChunkDemuxer> chunk_demuxer_; | 115 scoped_refptr<ChunkDemuxer> chunk_demuxer_; |
107 AesDecryptor* decryptor_; | 116 AesDecryptor* decryptor_; |
108 }; | 117 }; |
109 | 118 |
110 class PipelineIntegrationTest | 119 class PipelineIntegrationTest |
111 : public testing::Test, | 120 : public testing::Test, |
112 public PipelineIntegrationTestBase { | 121 public PipelineIntegrationTestBase { |
113 public: | 122 public: |
114 void StartPipelineWithMediaSource(MockMediaSource& source) { | 123 void StartPipelineWithMediaSource(MockMediaSource& source) { |
115 pipeline_->Start( | 124 pipeline_->Start( |
116 CreateFilterCollection(&source), | 125 CreateFilterCollection(&source), |
117 base::Bind(&PipelineIntegrationTest::OnEnded, base::Unretained(this)), | 126 base::Bind(&PipelineIntegrationTest::OnEnded, base::Unretained(this)), |
118 base::Bind(&PipelineIntegrationTest::OnError, base::Unretained(this)), | 127 base::Bind(&PipelineIntegrationTest::OnError, base::Unretained(this)), |
119 QuitOnStatusCB(PIPELINE_OK)); | 128 QuitOnStatusCB(PIPELINE_OK)); |
120 | 129 |
121 ASSERT_TRUE(decoder_.get()); | 130 ASSERT_TRUE(decoder_.get()); |
122 source.set_decryptor(decryptor_.get()); | 131 source.set_decryptor(decryptor_.get()); |
123 | 132 |
124 message_loop_.Run(); | 133 message_loop_.Run(); |
125 } | 134 } |
126 | 135 |
127 // Verifies that seeking works properly for ChunkDemuxer when the | 136 // Verifies that seeking works properly for ChunkDemuxer when the |
128 // seek happens while there is a pending read on the ChunkDemuxer | 137 // seek happens while there is a pending read on the ChunkDemuxer |
129 // and no data is available. | 138 // and no data is available. |
130 bool TestSeekDuringRead(const std::string& filename, | 139 bool TestSeekDuringRead(const std::string& filename, |
131 int initial_append_size, | 140 int initial_append_size, |
132 base::TimeDelta start_seek_time, | 141 base::TimeDelta start_seek_time, |
133 base::TimeDelta seek_time, | 142 base::TimeDelta seek_time, |
134 int seek_file_position, | 143 int seek_file_position, |
135 int seek_append_size) { | 144 int seek_append_size, |
136 MockMediaSource source(filename, initial_append_size); | 145 bool has_audio, |
| 146 bool has_video) { |
| 147 MockMediaSource source(filename, initial_append_size, has_audio, has_video); |
137 StartPipelineWithMediaSource(source); | 148 StartPipelineWithMediaSource(source); |
138 | 149 |
139 if (pipeline_status_ != PIPELINE_OK) | 150 if (pipeline_status_ != PIPELINE_OK) |
140 return false; | 151 return false; |
141 | 152 |
142 Play(); | 153 Play(); |
143 if (!WaitUntilCurrentTimeIsAfter(start_seek_time)) | 154 if (!WaitUntilCurrentTimeIsAfter(start_seek_time)) |
144 return false; | 155 return false; |
145 | 156 |
146 source.Seek(seek_file_position, seek_append_size); | 157 source.Seek(seek_file_position, seek_append_size); |
(...skipping 22 matching lines...) Expand all Loading... |
169 | 180 |
170 Play(); | 181 Play(); |
171 | 182 |
172 ASSERT_TRUE(WaitUntilOnEnded()); | 183 ASSERT_TRUE(WaitUntilOnEnded()); |
173 | 184 |
174 EXPECT_EQ(GetVideoHash(), "f0be120a90a811506777c99a2cdf7cc1"); | 185 EXPECT_EQ(GetVideoHash(), "f0be120a90a811506777c99a2cdf7cc1"); |
175 EXPECT_EQ(GetAudioHash(), "6138555be3389e6aba4c8e6f70195d50"); | 186 EXPECT_EQ(GetAudioHash(), "6138555be3389e6aba4c8e6f70195d50"); |
176 } | 187 } |
177 | 188 |
178 TEST_F(PipelineIntegrationTest, EncryptedPlayback) { | 189 TEST_F(PipelineIntegrationTest, EncryptedPlayback) { |
179 MockMediaSource source("bear-320x240-encrypted.webm", 219726); | 190 MockMediaSource source("bear-320x240-encrypted.webm", 219726, true, true); |
180 StartPipelineWithMediaSource(source); | 191 StartPipelineWithMediaSource(source); |
181 | 192 |
182 source.EndOfStream(); | 193 source.EndOfStream(); |
183 ASSERT_EQ(PIPELINE_OK, pipeline_status_); | 194 ASSERT_EQ(PIPELINE_OK, pipeline_status_); |
184 | 195 |
185 Play(); | 196 Play(); |
186 | 197 |
187 ASSERT_TRUE(WaitUntilOnEnded()); | 198 ASSERT_TRUE(WaitUntilOnEnded()); |
188 source.Abort(); | 199 source.Abort(); |
189 Stop(); | 200 Stop(); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 ASSERT_TRUE(Seek(seek_time)); | 242 ASSERT_TRUE(Seek(seek_time)); |
232 EXPECT_GE(pipeline_->GetCurrentTime(), seek_time); | 243 EXPECT_GE(pipeline_->GetCurrentTime(), seek_time); |
233 ASSERT_TRUE(WaitUntilOnEnded()); | 244 ASSERT_TRUE(WaitUntilOnEnded()); |
234 } | 245 } |
235 | 246 |
236 // Verify audio decoder & renderer can handle aborted demuxer reads. | 247 // Verify audio decoder & renderer can handle aborted demuxer reads. |
237 TEST_F(PipelineIntegrationTest, ChunkDemuxerAbortRead_AudioOnly) { | 248 TEST_F(PipelineIntegrationTest, ChunkDemuxerAbortRead_AudioOnly) { |
238 ASSERT_TRUE(TestSeekDuringRead("bear-320x240-audio-only.webm", 8192, | 249 ASSERT_TRUE(TestSeekDuringRead("bear-320x240-audio-only.webm", 8192, |
239 base::TimeDelta::FromMilliseconds(464), | 250 base::TimeDelta::FromMilliseconds(464), |
240 base::TimeDelta::FromMilliseconds(617), | 251 base::TimeDelta::FromMilliseconds(617), |
241 0x10CA, 19730)); | 252 0x10CA, 19730, true, false)); |
242 } | 253 } |
243 | 254 |
244 // Verify video decoder & renderer can handle aborted demuxer reads. | 255 // Verify video decoder & renderer can handle aborted demuxer reads. |
245 TEST_F(PipelineIntegrationTest, ChunkDemuxerAbortRead_VideoOnly) { | 256 TEST_F(PipelineIntegrationTest, ChunkDemuxerAbortRead_VideoOnly) { |
246 ASSERT_TRUE(TestSeekDuringRead("bear-320x240-video-only.webm", 32768, | 257 ASSERT_TRUE(TestSeekDuringRead("bear-320x240-video-only.webm", 32768, |
247 base::TimeDelta::FromMilliseconds(200), | 258 base::TimeDelta::FromMilliseconds(200), |
248 base::TimeDelta::FromMilliseconds(1668), | 259 base::TimeDelta::FromMilliseconds(1668), |
249 0x1C896, 65536)); | 260 0x1C896, 65536, false, true)); |
250 } | 261 } |
251 | 262 |
252 } // namespace media | 263 } // namespace media |
OLD | NEW |