Index: media/filters/chunk_demuxer_unittest.cc |
diff --git a/media/filters/chunk_demuxer_unittest.cc b/media/filters/chunk_demuxer_unittest.cc |
index 13d0c93d5b09d2c55f151ac28cc09dda810708d9..4dbed5bf1403fc9c0975fd5649ce2977051388de 100644 |
--- a/media/filters/chunk_demuxer_unittest.cc |
+++ b/media/filters/chunk_demuxer_unittest.cc |
@@ -5,15 +5,18 @@ |
#include "base/base_paths.h" |
#include "base/bind.h" |
#include "base/file_util.h" |
+#include "base/message_loop.h" |
#include "base/path_service.h" |
#include "media/base/media.h" |
#include "media/base/mock_callback.h" |
#include "media/base/mock_ffmpeg.h" |
+#include "media/base/mock_filter_host.h" |
#include "media/filters/chunk_demuxer.h" |
#include "media/filters/chunk_demuxer_client.h" |
#include "media/webm/cluster_builder.h" |
#include "testing/gtest/include/gtest/gtest.h" |
+using ::testing::AnyNumber; |
using ::testing::InSequence; |
using ::testing::Return; |
using ::testing::SetArgumentPointee; |
@@ -72,6 +75,7 @@ class ChunkDemuxerTest : public testing::Test{ |
} |
virtual ~ChunkDemuxerTest() { |
+ message_loop_.RunAllPending(); |
Ami GONE FROM CHROMIUM
2011/08/03 21:06:02
This makes me worry. Why do you have it?
acolwell GONE FROM CHROMIUM
2011/08/03 22:08:11
It was just catching the error on EndOfStream() ca
|
ShutdownDemuxer(); |
} |
@@ -149,6 +153,14 @@ class ChunkDemuxerTest : public testing::Test{ |
} |
} |
+ void AppendData(const uint8* data, unsigned length) { |
+ EXPECT_CALL(mock_filter_host_, SetBufferedBytes(_)).Times(AnyNumber()); |
+ EXPECT_CALL(mock_filter_host_, SetBufferedTime(_)).Times(AnyNumber()); |
+ EXPECT_CALL(mock_filter_host_, SetNetworkActivity(true)).Times(AnyNumber()); |
Ami GONE FROM CHROMIUM
2011/08/03 21:06:02
Ugh to the above three lines, and the other green
acolwell GONE FROM CHROMIUM
2011/08/03 22:08:11
Yes. Yes I can...These are on the must die list al
|
+ EXPECT_TRUE(demuxer_->AppendData(data, length)); |
+ message_loop_.RunAllPending(); |
+ } |
+ |
void AppendInfoTracks(bool has_audio, bool has_video) { |
EXPECT_CALL(mock_ffmpeg_, AVOpenInputFile(_, _, NULL, 0, NULL)) |
.WillOnce(DoAll(SetArgumentPointee<0>(&format_context_), |
@@ -168,7 +180,7 @@ class ChunkDemuxerTest : public testing::Test{ |
SetupAVFormatContext(has_audio, has_video); |
- demuxer_->AppendData(info_tracks.get(), info_tracks_size); |
+ AppendData(info_tracks.get(), info_tracks_size); |
} |
static void InitDoneCalled(bool* was_called, PipelineStatus expectedStatus, |
@@ -192,6 +204,9 @@ class ChunkDemuxerTest : public testing::Test{ |
AppendInfoTracks(has_audio, has_video); |
EXPECT_TRUE(init_done_called); |
+ EXPECT_CALL(mock_filter_host_, SetDuration(_)); |
+ EXPECT_CALL(mock_filter_host_, SetCurrentReadPosition(_)); |
+ demuxer_->set_host(&mock_filter_host_); |
} |
void ShutdownDemuxer() { |
@@ -214,7 +229,9 @@ class ChunkDemuxerTest : public testing::Test{ |
MOCK_METHOD1(Checkpoint, void(int id)); |
+ MessageLoop message_loop_; |
Ami GONE FROM CHROMIUM
2011/08/03 21:06:02
I don't get where this is populated, only drained.
acolwell GONE FROM CHROMIUM
2011/08/03 22:08:11
The constructor is magical and initializes the thr
Ami GONE FROM CHROMIUM
2011/08/03 23:41:35
Per offline convo, I think you can avoid ML entire
acolwell GONE FROM CHROMIUM
2011/08/04 00:22:16
Removed
|
MockFFmpeg mock_ffmpeg_; |
+ MockFilterHost mock_filter_host_; |
AVFormatContext format_context_; |
AVCodecContext codecs_[MAX_CODECS_INDEX]; |
@@ -299,7 +316,7 @@ TEST_F(ChunkDemuxerTest, TestAppendDataAfterSeek) { |
Checkpoint(1); |
- EXPECT_TRUE(demuxer_->AppendData(cluster->data(), cluster->size())); |
+ AppendData(cluster->data(), cluster->size()); |
Checkpoint(2); |
} |
@@ -345,7 +362,7 @@ TEST_F(ChunkDemuxerTest, TestRead) { |
AddSimpleBlock(&cb, kVideoTrackNum, 123); |
scoped_ptr<Cluster> cluster(cb.Finish()); |
- EXPECT_TRUE(demuxer_->AppendData(cluster->data(), cluster->size())); |
+ AppendData(cluster->data(), cluster->size()); |
EXPECT_TRUE(audio_read_done); |
EXPECT_TRUE(video_read_done); |
@@ -363,7 +380,7 @@ TEST_F(ChunkDemuxerTest, TestOutOfOrderClusters) { |
AddSimpleBlock(&cb, kVideoTrackNum, 43); |
scoped_ptr<Cluster> clusterA(cb.Finish()); |
- EXPECT_TRUE(demuxer_->AppendData(clusterA->data(), clusterA->size())); |
+ AppendData(clusterA->data(), clusterA->size()); |
// Cluster B starts before clusterA and has data |
// that overlaps. |
@@ -376,35 +393,24 @@ TEST_F(ChunkDemuxerTest, TestOutOfOrderClusters) { |
// Make sure that AppendData() fails because this cluster data |
// is before previous data. |
- EXPECT_FALSE(demuxer_->AppendData(clusterB->data(), clusterB->size())); |
+ EXPECT_CALL(mock_filter_host_, SetError(PIPELINE_ERROR_DECODE)); |
+ AppendData(clusterB->data(), clusterB->size()); |
- // Cluster C starts after clusterA. |
- cb.SetClusterTimecode(56); |
- AddSimpleBlock(&cb, kAudioTrackNum, 56); |
- AddSimpleBlock(&cb, kVideoTrackNum, 76); |
- AddSimpleBlock(&cb, kAudioTrackNum, 79); |
- AddSimpleBlock(&cb, kVideoTrackNum, 109); |
+ // Verify that AppendData() doesn't accept more data now. |
+ cb.SetClusterTimecode(45); |
+ AddSimpleBlock(&cb, kAudioTrackNum, 45); |
+ AddSimpleBlock(&cb, kVideoTrackNum, 45); |
scoped_ptr<Cluster> clusterC(cb.Finish()); |
- |
- // Verify that clusterC is accepted. |
- EXPECT_TRUE(demuxer_->AppendData(clusterC->data(), clusterC->size())); |
- |
- // Flush and try clusterB again. |
- demuxer_->FlushData(); |
- EXPECT_TRUE(demuxer_->AppendData(clusterB->data(), clusterB->size())); |
- |
- // Following that with clusterC should work too since it doesn't |
- // overlap with clusterB. |
- EXPECT_TRUE(demuxer_->AppendData(clusterC->data(), clusterC->size())); |
+ EXPECT_FALSE(demuxer_->AppendData(clusterC->data(), clusterC->size())); |
} |
-TEST_F(ChunkDemuxerTest, TestInvalidBlockSequences) { |
+TEST_F(ChunkDemuxerTest, TestNonMonotonicButAboveClusterTimecode) { |
InitDemuxer(true, true); |
ClusterBuilder cb; |
- // Test the case where timecode is not monotonically |
- // increasing but stays above the cluster timecode. |
+ // Test the case where block timecodes are not monotonically |
+ // increasing but stay above the cluster timecode. |
cb.SetClusterTimecode(5); |
AddSimpleBlock(&cb, kAudioTrackNum, 5); |
AddSimpleBlock(&cb, kVideoTrackNum, 10); |
@@ -412,17 +418,47 @@ TEST_F(ChunkDemuxerTest, TestInvalidBlockSequences) { |
AddSimpleBlock(&cb, kVideoTrackNum, 15); |
scoped_ptr<Cluster> clusterA(cb.Finish()); |
- EXPECT_FALSE(demuxer_->AppendData(clusterA->data(), clusterA->size())); |
+ EXPECT_CALL(mock_filter_host_, SetError(PIPELINE_ERROR_DECODE)); |
+ AppendData(clusterA->data(), clusterA->size()); |
+ |
+ // Verify that AppendData() doesn't accept more data now. |
+ cb.SetClusterTimecode(20); |
+ AddSimpleBlock(&cb, kAudioTrackNum, 20); |
+ AddSimpleBlock(&cb, kVideoTrackNum, 20); |
+ scoped_ptr<Cluster> clusterB(cb.Finish()); |
+ EXPECT_FALSE(demuxer_->AppendData(clusterB->data(), clusterB->size())); |
+} |
+ |
+TEST_F(ChunkDemuxerTest, TestBackwardsAndBeforeClusterTimecode) { |
+ InitDemuxer(true, true); |
+ |
+ ClusterBuilder cb; |
- // Test timecodes going backwards before cluster timecode. |
+ // Test timecodes going backwards and including values less than the cluster |
+ // timecode. |
cb.SetClusterTimecode(5); |
AddSimpleBlock(&cb, kAudioTrackNum, 5); |
AddSimpleBlock(&cb, kVideoTrackNum, 5); |
AddSimpleBlock(&cb, kAudioTrackNum, 3); |
AddSimpleBlock(&cb, kVideoTrackNum, 3); |
- scoped_ptr<Cluster> clusterB(cb.Finish()); |
+ scoped_ptr<Cluster> clusterA(cb.Finish()); |
+ |
+ EXPECT_CALL(mock_filter_host_, SetError(PIPELINE_ERROR_DECODE)); |
+ AppendData(clusterA->data(), clusterA->size()); |
+ // Verify that AppendData() doesn't accept more data now. |
+ cb.SetClusterTimecode(6); |
+ AddSimpleBlock(&cb, kAudioTrackNum, 6); |
+ AddSimpleBlock(&cb, kVideoTrackNum, 6); |
+ scoped_ptr<Cluster> clusterB(cb.Finish()); |
EXPECT_FALSE(demuxer_->AppendData(clusterB->data(), clusterB->size())); |
+} |
+ |
+ |
+TEST_F(ChunkDemuxerTest, TestPerStreamMonotonicallyIncreasingTimestamps) { |
+ InitDemuxer(true, true); |
+ |
+ ClusterBuilder cb; |
// Test strict monotonic increasing timestamps on a per stream |
// basis. |
@@ -431,25 +467,40 @@ TEST_F(ChunkDemuxerTest, TestInvalidBlockSequences) { |
AddSimpleBlock(&cb, kVideoTrackNum, 5); |
AddSimpleBlock(&cb, kAudioTrackNum, 5); |
AddSimpleBlock(&cb, kVideoTrackNum, 7); |
- scoped_ptr<Cluster> clusterC(cb.Finish()); |
+ scoped_ptr<Cluster> cluster(cb.Finish()); |
- EXPECT_FALSE(demuxer_->AppendData(clusterC->data(), clusterC->size())); |
+ EXPECT_CALL(mock_filter_host_, SetError(PIPELINE_ERROR_DECODE)); |
+ AppendData(cluster->data(), cluster->size()); |
+} |
+ |
+TEST_F(ChunkDemuxerTest, TestMonotonicallyIncreasingTimestampsAcrossClusters) { |
+ InitDemuxer(true, true); |
+ |
+ ClusterBuilder cb; |
// Test strict monotonic increasing timestamps on a per stream |
// basis across clusters. |
cb.SetClusterTimecode(5); |
AddSimpleBlock(&cb, kAudioTrackNum, 5); |
AddSimpleBlock(&cb, kVideoTrackNum, 5); |
- scoped_ptr<Cluster> clusterD(cb.Finish()); |
+ scoped_ptr<Cluster> clusterA(cb.Finish()); |
- EXPECT_TRUE(demuxer_->AppendData(clusterD->data(), clusterD->size())); |
+ AppendData(clusterA->data(), clusterA->size()); |
cb.SetClusterTimecode(5); |
AddSimpleBlock(&cb, kAudioTrackNum, 5); |
AddSimpleBlock(&cb, kVideoTrackNum, 7); |
- scoped_ptr<Cluster> clusterE(cb.Finish()); |
+ scoped_ptr<Cluster> clusterB(cb.Finish()); |
- EXPECT_FALSE(demuxer_->AppendData(clusterE->data(), clusterE->size())); |
+ EXPECT_CALL(mock_filter_host_, SetError(PIPELINE_ERROR_DECODE)); |
+ AppendData(clusterB->data(), clusterB->size()); |
+ |
+ // Verify that AppendData() doesn't accept more data now. |
+ cb.SetClusterTimecode(10); |
+ AddSimpleBlock(&cb, kAudioTrackNum, 10); |
+ AddSimpleBlock(&cb, kVideoTrackNum, 10); |
+ scoped_ptr<Cluster> clusterC(cb.Finish()); |
+ EXPECT_FALSE(demuxer_->AppendData(clusterC->data(), clusterC->size())); |
} |
// Test the case where a cluster is passed to AppendData() before |
@@ -463,14 +514,46 @@ TEST_F(ChunkDemuxerTest, TestClusterBeforeInfoTracks) { |
AddSimpleBlock(&cb, kVideoTrackNum, 0); |
scoped_ptr<Cluster> cluster(cb.Finish()); |
- EXPECT_FALSE(demuxer_->AppendData(cluster->data(), cluster->size())); |
+ AppendData(cluster->data(), cluster->size()); |
} |
- |
// Test cases where we get an EndOfStream() call during initialization. |
TEST_F(ChunkDemuxerTest, TestEOSDuringInit) { |
EXPECT_CALL(*client_, DemuxerOpened(_)); |
demuxer_->Init(NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); |
demuxer_->EndOfStream(PIPELINE_OK); |
} |
+ |
+TEST_F(ChunkDemuxerTest, TestDecodeErrorEndOfStream) { |
+ InitDemuxer(true, true); |
+ |
+ ClusterBuilder cb; |
+ cb.SetClusterTimecode(0); |
+ AddSimpleBlock(&cb, kAudioTrackNum, 0); |
+ AddSimpleBlock(&cb, kVideoTrackNum, 0); |
+ AddSimpleBlock(&cb, kAudioTrackNum, 23); |
+ AddSimpleBlock(&cb, kVideoTrackNum, 33); |
+ scoped_ptr<Cluster> cluster(cb.Finish()); |
+ AppendData(cluster->data(), cluster->size()); |
+ |
+ EXPECT_CALL(mock_filter_host_, SetError(PIPELINE_ERROR_DECODE)); |
+ demuxer_->EndOfStream(PIPELINE_ERROR_DECODE); |
+} |
+ |
+TEST_F(ChunkDemuxerTest, TestNetworkErrorEndOfStream) { |
+ InitDemuxer(true, true); |
+ |
+ ClusterBuilder cb; |
+ cb.SetClusterTimecode(0); |
+ AddSimpleBlock(&cb, kAudioTrackNum, 0); |
+ AddSimpleBlock(&cb, kVideoTrackNum, 0); |
+ AddSimpleBlock(&cb, kAudioTrackNum, 23); |
+ AddSimpleBlock(&cb, kVideoTrackNum, 33); |
+ scoped_ptr<Cluster> cluster(cb.Finish()); |
+ AppendData(cluster->data(), cluster->size()); |
+ |
+ EXPECT_CALL(mock_filter_host_, SetError(PIPELINE_ERROR_NETWORK)); |
+ demuxer_->EndOfStream(PIPELINE_ERROR_NETWORK); |
+} |
+ |
} // namespace media |