Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(165)

Unified Diff: media/filters/chunk_demuxer_unittest.cc

Issue 7538027: Make ChunkDemuxer error handling more consistent and robust. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix unittests. Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698