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 <stddef.h> | 5 #include <stddef.h> |
6 #include <stdint.h> | 6 #include <stdint.h> |
7 | 7 |
8 #include <algorithm> | 8 #include <algorithm> |
9 #include <deque> | 9 #include <deque> |
10 #include <string> | 10 #include <string> |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 media::PipelineStatus expected_pipeline_status) { | 134 media::PipelineStatus expected_pipeline_status) { |
135 InitializeDemuxerInternal(/*enable_text=*/false, expected_pipeline_status, | 135 InitializeDemuxerInternal(/*enable_text=*/false, expected_pipeline_status, |
136 base::Time()); | 136 base::Time()); |
137 } | 137 } |
138 | 138 |
139 MOCK_METHOD2(OnReadDoneCalled, void(int, int64_t)); | 139 MOCK_METHOD2(OnReadDoneCalled, void(int, int64_t)); |
140 | 140 |
141 struct ReadExpectation { | 141 struct ReadExpectation { |
142 ReadExpectation(size_t size, | 142 ReadExpectation(size_t size, |
143 int64_t timestamp_us, | 143 int64_t timestamp_us, |
144 const base::TimeDelta& discard_front_padding, | 144 base::TimeDelta discard_front_padding, |
145 bool is_key_frame) | 145 bool is_key_frame, |
| 146 DemuxerStream::Status status) |
146 : size(size), | 147 : size(size), |
147 timestamp_us(timestamp_us), | 148 timestamp_us(timestamp_us), |
148 discard_front_padding(discard_front_padding), | 149 discard_front_padding(discard_front_padding), |
149 is_key_frame(is_key_frame) {} | 150 is_key_frame(is_key_frame), |
| 151 status(status) {} |
150 | 152 |
151 size_t size; | 153 size_t size; |
152 int64_t timestamp_us; | 154 int64_t timestamp_us; |
153 base::TimeDelta discard_front_padding; | 155 base::TimeDelta discard_front_padding; |
154 bool is_key_frame; | 156 bool is_key_frame; |
| 157 DemuxerStream::Status status; |
155 }; | 158 }; |
156 | 159 |
157 // Verifies that |buffer| has a specific |size| and |timestamp|. | 160 // Verifies that |buffer| has a specific |size| and |timestamp|. |
158 // |location| simply indicates where the call to this function was made. | 161 // |location| simply indicates where the call to this function was made. |
159 // This makes it easier to track down where test failures occur. | 162 // This makes it easier to track down where test failures occur. |
160 void OnReadDone(const tracked_objects::Location& location, | 163 void OnReadDone(const tracked_objects::Location& location, |
161 const ReadExpectation& read_expectation, | 164 const ReadExpectation& read_expectation, |
162 DemuxerStream::Status status, | 165 DemuxerStream::Status status, |
163 const scoped_refptr<DecoderBuffer>& buffer) { | 166 const scoped_refptr<DecoderBuffer>& buffer) { |
164 std::string location_str; | 167 std::string location_str; |
165 location.Write(true, false, &location_str); | 168 location.Write(true, false, &location_str); |
166 location_str += "\n"; | 169 location_str += "\n"; |
167 SCOPED_TRACE(location_str); | 170 SCOPED_TRACE(location_str); |
168 EXPECT_EQ(status, DemuxerStream::kOk); | 171 EXPECT_EQ(read_expectation.status, status); |
169 EXPECT_TRUE(buffer.get() != NULL); | 172 if (status == DemuxerStream::kOk) { |
170 EXPECT_EQ(read_expectation.size, buffer->data_size()); | 173 EXPECT_TRUE(buffer); |
171 EXPECT_EQ(read_expectation.timestamp_us, | 174 EXPECT_EQ(read_expectation.size, buffer->data_size()); |
172 buffer->timestamp().InMicroseconds()); | 175 EXPECT_EQ(read_expectation.timestamp_us, |
173 EXPECT_EQ(read_expectation.discard_front_padding, | 176 buffer->timestamp().InMicroseconds()); |
174 buffer->discard_padding().first); | 177 EXPECT_EQ(read_expectation.discard_front_padding, |
175 EXPECT_EQ(read_expectation.is_key_frame, buffer->is_key_frame()); | 178 buffer->discard_padding().first); |
| 179 EXPECT_EQ(read_expectation.is_key_frame, buffer->is_key_frame()); |
| 180 } |
176 DCHECK_EQ(&message_loop_, base::MessageLoop::current()); | 181 DCHECK_EQ(&message_loop_, base::MessageLoop::current()); |
177 OnReadDoneCalled(read_expectation.size, read_expectation.timestamp_us); | 182 OnReadDoneCalled(read_expectation.size, read_expectation.timestamp_us); |
178 message_loop_.task_runner()->PostTask( | 183 message_loop_.task_runner()->PostTask( |
179 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); | 184 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); |
180 } | 185 } |
181 | 186 |
182 DemuxerStream::ReadCB NewReadCB(const tracked_objects::Location& location, | 187 DemuxerStream::ReadCB NewReadCB( |
183 int size, | 188 const tracked_objects::Location& location, |
184 int64_t timestamp_us, | 189 int size, |
185 bool is_key_frame) { | 190 int64_t timestamp_us, |
186 return NewReadCBWithCheckedDiscard(location, | 191 bool is_key_frame, |
187 size, | 192 DemuxerStream::Status status = DemuxerStream::kOk) { |
188 timestamp_us, | 193 return NewReadCBWithCheckedDiscard(location, size, timestamp_us, |
189 base::TimeDelta(), | 194 base::TimeDelta(), is_key_frame, status); |
190 is_key_frame); | |
191 } | 195 } |
192 | 196 |
193 DemuxerStream::ReadCB NewReadCBWithCheckedDiscard( | 197 DemuxerStream::ReadCB NewReadCBWithCheckedDiscard( |
194 const tracked_objects::Location& location, | 198 const tracked_objects::Location& location, |
195 int size, | 199 int size, |
196 int64_t timestamp_us, | 200 int64_t timestamp_us, |
197 base::TimeDelta discard_front_padding, | 201 base::TimeDelta discard_front_padding, |
198 bool is_key_frame) { | 202 bool is_key_frame, |
| 203 DemuxerStream::Status status = DemuxerStream::kOk) { |
199 EXPECT_CALL(*this, OnReadDoneCalled(size, timestamp_us)); | 204 EXPECT_CALL(*this, OnReadDoneCalled(size, timestamp_us)); |
200 | 205 |
201 struct ReadExpectation read_expectation(size, | 206 struct ReadExpectation read_expectation( |
202 timestamp_us, | 207 size, timestamp_us, discard_front_padding, is_key_frame, status); |
203 discard_front_padding, | |
204 is_key_frame); | |
205 | 208 |
206 return base::Bind(&FFmpegDemuxerTest::OnReadDone, | 209 return base::Bind(&FFmpegDemuxerTest::OnReadDone, |
207 base::Unretained(this), | 210 base::Unretained(this), |
208 location, | 211 location, |
209 read_expectation); | 212 read_expectation); |
210 } | 213 } |
211 | 214 |
212 MOCK_METHOD2(OnEncryptedMediaInitData, | 215 MOCK_METHOD2(OnEncryptedMediaInitData, |
213 void(EmeInitDataType init_data_type, | 216 void(EmeInitDataType init_data_type, |
214 const std::vector<uint8_t>& init_data)); | 217 const std::vector<uint8_t>& init_data)); |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 EmeInitDataType::WEBM, | 414 EmeInitDataType::WEBM, |
412 std::vector<uint8_t>(kEncryptedMediaInitData, | 415 std::vector<uint8_t>(kEncryptedMediaInitData, |
413 kEncryptedMediaInitData + | 416 kEncryptedMediaInitData + |
414 arraysize(kEncryptedMediaInitData)))) | 417 arraysize(kEncryptedMediaInitData)))) |
415 .Times(Exactly(2)); | 418 .Times(Exactly(2)); |
416 | 419 |
417 CreateDemuxer("bear-320x240-av_enc-av.webm"); | 420 CreateDemuxer("bear-320x240-av_enc-av.webm"); |
418 InitializeDemuxer(); | 421 InitializeDemuxer(); |
419 } | 422 } |
420 | 423 |
| 424 TEST_F(FFmpegDemuxerTest, AbortPendingReads) { |
| 425 // We test that on a successful audio packet read. |
| 426 CreateDemuxer("bear-320x240.webm"); |
| 427 InitializeDemuxer(); |
| 428 |
| 429 // Attempt a read from the audio stream and run the message loop until done. |
| 430 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 431 |
| 432 // Depending on where in the reading process ffmpeg is, an error may cause the |
| 433 // stream to be marked as EOF. Simulate this here to ensure it is properly |
| 434 // cleared by the AbortPendingReads() call. |
| 435 format_context()->pb->eof_reached = 1; |
| 436 audio->Read(NewReadCB(FROM_HERE, 29, 0, true, DemuxerStream::kAborted)); |
| 437 demuxer_->AbortPendingReads(); |
| 438 base::RunLoop().Run(); |
| 439 |
| 440 // Ensure blocking thread has completed outstanding work. |
| 441 demuxer_->Stop(); |
| 442 EXPECT_EQ(format_context()->pb->eof_reached, 0); |
| 443 demuxer_.reset(); |
| 444 } |
| 445 |
421 TEST_F(FFmpegDemuxerTest, Read_Audio) { | 446 TEST_F(FFmpegDemuxerTest, Read_Audio) { |
422 // We test that on a successful audio packet read. | 447 // We test that on a successful audio packet read. |
423 CreateDemuxer("bear-320x240.webm"); | 448 CreateDemuxer("bear-320x240.webm"); |
424 InitializeDemuxer(); | 449 InitializeDemuxer(); |
425 | 450 |
426 // Attempt a read from the audio stream and run the message loop until done. | 451 // Attempt a read from the audio stream and run the message loop until done. |
427 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); | 452 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); |
428 | 453 |
429 audio->Read(NewReadCB(FROM_HERE, 29, 0, true)); | 454 audio->Read(NewReadCB(FROM_HERE, 29, 0, true)); |
430 base::RunLoop().Run(); | 455 base::RunLoop().Run(); |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
841 | 866 |
842 // Video read #1. | 867 // Video read #1. |
843 video->Read(NewReadCB(FROM_HERE, 5425, 801000, true)); | 868 video->Read(NewReadCB(FROM_HERE, 5425, 801000, true)); |
844 base::RunLoop().Run(); | 869 base::RunLoop().Run(); |
845 | 870 |
846 // Video read #2. | 871 // Video read #2. |
847 video->Read(NewReadCB(FROM_HERE, 1906, 834000, false)); | 872 video->Read(NewReadCB(FROM_HERE, 1906, 834000, false)); |
848 base::RunLoop().Run(); | 873 base::RunLoop().Run(); |
849 } | 874 } |
850 | 875 |
| 876 TEST_F(FFmpegDemuxerTest, CancelledSeek) { |
| 877 CreateDemuxer("bear-320x240.webm"); |
| 878 InitializeDemuxer(); |
| 879 |
| 880 // Get our streams. |
| 881 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 882 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 883 ASSERT_TRUE(video); |
| 884 ASSERT_TRUE(audio); |
| 885 |
| 886 // Read a video packet and release it. |
| 887 video->Read(NewReadCB(FROM_HERE, 22084, 0, true)); |
| 888 base::RunLoop().Run(); |
| 889 |
| 890 // Issue a simple forward seek, which should discard queued packets. |
| 891 WaitableMessageLoopEvent event; |
| 892 demuxer_->Seek(base::TimeDelta::FromMicroseconds(1000000), |
| 893 event.GetPipelineStatusCB()); |
| 894 // FFmpegDemuxer does not care what the previous seek time was when canceling. |
| 895 demuxer_->CancelPendingSeek(base::TimeDelta::FromSeconds(12345)); |
| 896 event.RunAndWaitForStatus(PIPELINE_OK); |
| 897 } |
| 898 |
851 TEST_F(FFmpegDemuxerTest, SeekText) { | 899 TEST_F(FFmpegDemuxerTest, SeekText) { |
852 // We're testing that the demuxer frees all queued packets when it receives | 900 // We're testing that the demuxer frees all queued packets when it receives |
853 // a Seek(). | 901 // a Seek(). |
854 CreateDemuxer("bear-vp8-webvtt.webm"); | 902 CreateDemuxer("bear-vp8-webvtt.webm"); |
855 DemuxerStream* text_stream = NULL; | 903 DemuxerStream* text_stream = NULL; |
856 EXPECT_CALL(host_, AddTextStream(_, _)) | 904 EXPECT_CALL(host_, AddTextStream(_, _)) |
857 .WillOnce(SaveArg<0>(&text_stream)); | 905 .WillOnce(SaveArg<0>(&text_stream)); |
858 InitializeDemuxerWithText(); | 906 InitializeDemuxerWithText(); |
859 ASSERT_TRUE(text_stream); | 907 ASSERT_TRUE(text_stream); |
860 EXPECT_EQ(DemuxerStream::TEXT, text_stream->type()); | 908 EXPECT_EQ(DemuxerStream::TEXT, text_stream->type()); |
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1277 | 1325 |
1278 const MediaTrack& audio_track = *(media_tracks_->tracks()[1]); | 1326 const MediaTrack& audio_track = *(media_tracks_->tracks()[1]); |
1279 EXPECT_EQ(audio_track.type(), MediaTrack::Audio); | 1327 EXPECT_EQ(audio_track.type(), MediaTrack::Audio); |
1280 EXPECT_EQ(audio_track.bytestream_track_id(), 2); | 1328 EXPECT_EQ(audio_track.bytestream_track_id(), 2); |
1281 EXPECT_EQ(audio_track.kind(), "main"); | 1329 EXPECT_EQ(audio_track.kind(), "main"); |
1282 EXPECT_EQ(audio_track.label(), ""); | 1330 EXPECT_EQ(audio_track.label(), ""); |
1283 EXPECT_EQ(audio_track.language(), ""); | 1331 EXPECT_EQ(audio_track.language(), ""); |
1284 } | 1332 } |
1285 | 1333 |
1286 } // namespace media | 1334 } // namespace media |
OLD | NEW |