Index: media/filters/video_frame_stream_unittest.cc |
diff --git a/media/filters/video_frame_stream_unittest.cc b/media/filters/video_frame_stream_unittest.cc |
index 5225e98a543e9cefc301b42727ac3ea6167e2c13..6b0caa6ef246cb6cb30684b30902bc2e55f53579 100644 |
--- a/media/filters/video_frame_stream_unittest.cc |
+++ b/media/filters/video_frame_stream_unittest.cc |
@@ -26,17 +26,34 @@ static const int kDecodingDelay = 7; |
namespace media { |
+struct VideoFrameStreamTestParams { |
+ VideoFrameStreamTestParams(bool is_encrypted, |
+ bool enable_get_decode_output, |
+ int decoding_delay, |
+ int parallel_decoding) |
+ : is_encrypted(is_encrypted), |
+ enable_get_decode_output(enable_get_decode_output), |
+ decoding_delay(decoding_delay), |
+ parallel_decoding(parallel_decoding) {} |
+ |
+ bool is_encrypted; |
+ bool enable_get_decode_output; |
+ int decoding_delay; |
+ int parallel_decoding; |
+}; |
+ |
class VideoFrameStreamTest |
: public testing::Test, |
- public testing::WithParamInterface<std::tr1::tuple<bool, bool> > { |
+ public testing::WithParamInterface<VideoFrameStreamTestParams> { |
public: |
VideoFrameStreamTest() |
: demuxer_stream_(new FakeDemuxerStream(kNumConfigs, |
kNumBuffersInOneConfig, |
- IsEncrypted())), |
+ GetParam().is_encrypted)), |
decryptor_(new NiceMock<MockDecryptor>()), |
- decoder_( |
- new FakeVideoDecoder(kDecodingDelay, IsGetDecodeOutputEnabled())), |
+ decoder_(new FakeVideoDecoder(GetParam().decoding_delay, |
+ GetParam().enable_get_decode_output, |
+ GetParam().parallel_decoding)), |
is_initialized_(false), |
num_decoded_frames_(0), |
pending_initialize_(false), |
@@ -73,14 +90,6 @@ class VideoFrameStreamTest |
EXPECT_FALSE(is_initialized_); |
} |
- bool IsEncrypted() { |
- return std::tr1::get<0>(GetParam()); |
- } |
- |
- bool IsGetDecodeOutputEnabled() { |
- return std::tr1::get<1>(GetParam()); |
- } |
- |
MOCK_METHOD1(SetDecryptorReadyCallback, void(const media::DecryptorReadyCB&)); |
void OnStatistics(const PipelineStatistics& statistics) { |
@@ -120,8 +129,8 @@ class VideoFrameStreamTest |
} |
DCHECK_EQ(stream_type, Decryptor::kVideo); |
- scoped_refptr<DecoderBuffer> decrypted = DecoderBuffer::CopyFrom( |
- encrypted->data(), encrypted->data_size()); |
+ scoped_refptr<DecoderBuffer> decrypted = |
+ DecoderBuffer::CopyFrom(encrypted->data(), encrypted->data_size()); |
decrypted->set_timestamp(encrypted->timestamp()); |
decrypted->set_duration(encrypted->duration()); |
decrypt_cb.Run(Decryptor::kSuccess, decrypted); |
@@ -131,16 +140,19 @@ class VideoFrameStreamTest |
void FrameReady(VideoFrameStream::Status status, |
const scoped_refptr<VideoFrame>& frame) { |
DCHECK(pending_read_); |
- // TODO(xhwang): Add test cases where the fake decoder returns error or |
- // the fake demuxer aborts demuxer read. |
- ASSERT_TRUE(status == VideoFrameStream::OK || |
- status == VideoFrameStream::ABORTED) << status; |
frame_read_ = frame; |
+ last_read_status_ = status; |
if (frame.get() && !frame->end_of_stream()) |
num_decoded_frames_++; |
pending_read_ = false; |
} |
+ void FrameReadyHoldDemuxer(VideoFrameStream::Status status, |
+ const scoped_refptr<VideoFrame>& frame) { |
+ FrameReady(status, frame); |
+ |
+ } |
+ |
void OnReset() { |
DCHECK(!pending_read_); |
DCHECK(pending_reset_); |
@@ -224,7 +236,7 @@ class VideoFrameStreamTest |
break; |
case DECODER_DECODE: |
- decoder_->HoldNextDecode(); |
+ decoder_->HoldDecode(); |
ReadUntilPending(); |
break; |
@@ -322,6 +334,7 @@ class VideoFrameStreamTest |
bool pending_stop_; |
int total_bytes_decoded_; |
scoped_refptr<VideoFrame> frame_read_; |
+ VideoFrameStream::Status last_read_status_; |
// Decryptor has no key to decrypt a frame. |
bool has_no_key_; |
@@ -330,14 +343,34 @@ class VideoFrameStreamTest |
DISALLOW_COPY_AND_ASSIGN(VideoFrameStreamTest); |
}; |
-INSTANTIATE_TEST_CASE_P(Clear, VideoFrameStreamTest, |
- testing::Combine(testing::Values(false), testing::Values(false))); |
-INSTANTIATE_TEST_CASE_P(Clear_GetDecodeOutput, VideoFrameStreamTest, |
- testing::Combine(testing::Values(false), testing::Values(true))); |
-INSTANTIATE_TEST_CASE_P(Encrypted, VideoFrameStreamTest, |
- testing::Combine(testing::Values(true), testing::Values(false))); |
-INSTANTIATE_TEST_CASE_P(Encrypted_GetDecodeOutput, VideoFrameStreamTest, |
- testing::Combine(testing::Values(true), testing::Values(true))); |
+INSTANTIATE_TEST_CASE_P( |
+ Clear, |
+ VideoFrameStreamTest, |
+ ::testing::Values( |
+ VideoFrameStreamTestParams(false, false, kDecodingDelay, 1))); |
+INSTANTIATE_TEST_CASE_P( |
+ Clear_GetDecodeOutput, |
+ VideoFrameStreamTest, |
+ ::testing::Values( |
+ VideoFrameStreamTestParams(false, true, kDecodingDelay, 1))); |
+INSTANTIATE_TEST_CASE_P( |
+ Encrypted, |
+ VideoFrameStreamTest, |
+ ::testing::Values( |
+ VideoFrameStreamTestParams(true, false, kDecodingDelay, 1))); |
+INSTANTIATE_TEST_CASE_P( |
+ Encrypted_GetDecodeOutput, |
+ VideoFrameStreamTest, |
+ ::testing::Values( |
+ VideoFrameStreamTestParams(true, true, kDecodingDelay, 1))); |
+ |
+INSTANTIATE_TEST_CASE_P( |
+ Clear_Parallel, |
+ VideoFrameStreamTest, |
+ ::testing::Values( |
+ VideoFrameStreamTestParams(true, false, 0, 3), |
+ VideoFrameStreamTestParams(true, false, kDecodingDelay, 3))); |
+ |
TEST_P(VideoFrameStreamTest, Initialization) { |
Initialize(); |
@@ -366,6 +399,36 @@ TEST_P(VideoFrameStreamTest, Read_AfterReset) { |
Read(); |
} |
+TEST_P(VideoFrameStreamTest, Read_BlockedDemuxer) { |
+ Initialize(); |
+ demuxer_stream_->HoldNextRead(); |
+ ReadOneFrame(); |
+ EXPECT_TRUE(pending_read_); |
+ |
+ int demuxed_frames = 0; |
xhwang
2014/04/29 20:01:26
nit: s/frame/buffer
Actually you can just use Fak
Sergey Ulanov
2014/04/30 18:56:52
Done.
|
+ |
+ // Pass frames from the demuxer to the VideoFrameStream until the first read |
+ // request is satisfied. |
+ while (pending_read_) { |
+ ++demuxed_frames; |
+ demuxer_stream_->SatisfyReadAndHoldNext(); |
+ message_loop_.RunUntilIdle(); |
+ } |
+ |
+ // Stream should have read at least one buffer from the demuxer, but not more |
+ // than decoding_delay-1. |
+ EXPECT_EQ(std::max(GetParam().decoding_delay - 1, 1), demuxed_frames); |
xhwang
2014/04/29 20:01:26
why? For example:
input: 1 2 3 ...
output: 1 2
Sergey Ulanov
2014/04/30 18:56:52
Yes, you are right. This should be
std::min(Get
|
+ |
+ // At this point the stream is waiting on read from the demuxer, but there is |
+ // no pending read from the stream. The stream should be blocked if we try |
+ // reading from it again. |
+ ReadUntilPending(); |
xhwang
2014/04/29 20:01:26
My original proposal is to add a test where we hav
Sergey Ulanov
2014/04/30 18:56:52
That's a good point. Added another test now.
|
+ |
+ demuxer_stream_->SatisfyRead(); |
+ message_loop_.RunUntilIdle(); |
+ EXPECT_FALSE(pending_read_); |
+} |
+ |
// No Reset() before initialization is successfully completed. |
TEST_P(VideoFrameStreamTest, Reset_AfterInitialization) { |
@@ -449,7 +512,7 @@ TEST_P(VideoFrameStreamTest, Stop_BeforeInitialization) { |
} |
TEST_P(VideoFrameStreamTest, Stop_DuringSetDecryptor) { |
- if (!IsEncrypted()) { |
+ if (!GetParam().is_encrypted) { |
DVLOG(1) << "SetDecryptor test only runs when the stream is encrytped."; |
return; |
} |
@@ -555,4 +618,38 @@ TEST_P(VideoFrameStreamTest, Stop_AfterRead_AfterReset) { |
Stop(); |
} |
+TEST_P(VideoFrameStreamTest, DecoderErrorWhenReading) { |
+ Initialize(); |
+ EnterPendingState(DECODER_DECODE); |
+ decoder_->SimulateError(); |
+ message_loop_.RunUntilIdle(); |
+ ASSERT_FALSE(pending_read_); |
+ ASSERT_EQ(VideoFrameStream::DECODE_ERROR, last_read_status_); |
+} |
+ |
+TEST_P(VideoFrameStreamTest, DecoderErrorWhenNotReading) { |
+ Initialize(); |
+ |
+ decoder_->HoldDecode(); |
+ ReadOneFrame(); |
+ EXPECT_TRUE(pending_read_); |
+ |
+ // Satisfy decode requests until we get the first frame out. |
+ while (pending_read_) { |
+ decoder_->SatisfySingleDecode(); |
+ message_loop_.RunUntilIdle(); |
+ } |
+ |
+ // Trigger an error in the decoding. |
+ decoder_->SimulateError(); |
+ |
+ // The error must surface from Read() as DECODE_ERROR. |
+ while (last_read_status_ == VideoFrameStream::OK) { |
+ ReadOneFrame(); |
+ message_loop_.RunUntilIdle(); |
+ EXPECT_FALSE(pending_read_); |
+ } |
+ EXPECT_EQ(VideoFrameStream::DECODE_ERROR, last_read_status_); |
+} |
+ |
} // namespace media |