| 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 0f6752d7dc3825754fcfbd9bdf277f92758579e1..88b5af8ae3b4f733e3bc6c39fd7d298ff1b8673b 100644
|
| --- a/media/filters/video_frame_stream_unittest.cc
|
| +++ b/media/filters/video_frame_stream_unittest.cc
|
| @@ -9,6 +9,7 @@
|
| #include "base/macros.h"
|
| #include "base/message_loop/message_loop.h"
|
| #include "base/run_loop.h"
|
| +#include "base/strings/string_number_conversions.h"
|
| #include "media/base/fake_demuxer_stream.h"
|
| #include "media/base/gmock_callback_support.h"
|
| #include "media/base/mock_filters.h"
|
| @@ -28,11 +29,15 @@ using ::testing::Return;
|
| using ::testing::SaveArg;
|
| using ::testing::StrictMock;
|
|
|
| -static const int kNumConfigs = 4;
|
| -static const int kNumBuffersInOneConfig = 5;
|
| -
|
| namespace media {
|
|
|
| +const int kNumConfigs = 4;
|
| +const int kNumBuffersInOneConfig = 5;
|
| +
|
| +static std::string GetDecoderName(int i) {
|
| + return std::string("VideoDecoder") + base::IntToString(i);
|
| +}
|
| +
|
| struct VideoFrameStreamTestParams {
|
| VideoFrameStreamTestParams(bool is_encrypted,
|
| bool has_decryptor,
|
| @@ -70,30 +75,32 @@ class VideoFrameStreamTest
|
| BytesDecodedCB bytes_decoded_cb = base::Bind(
|
| &VideoFrameStreamTest::OnBytesDecoded, base::Unretained(this));
|
|
|
| - decoder1_ = new FakeVideoDecoder(decoding_delay, parallel_decoding,
|
| - bytes_decoded_cb);
|
| - decoder2_ = new FakeVideoDecoder(decoding_delay, parallel_decoding,
|
| - bytes_decoded_cb);
|
| - decoder3_ = new FakeVideoDecoder(decoding_delay, parallel_decoding,
|
| - bytes_decoded_cb);
|
| -
|
| + // Provide 3 decoders to test fallback cases.
|
| // TODO(xhwang): We should test the case where only certain decoder
|
| // supports encrypted streams. Currently this is hard to test because we use
|
| // parameterized tests which need to pass in all combinations.
|
| - if (GetParam().is_encrypted && !GetParam().has_decryptor) {
|
| - decoder1_->EnableEncryptedConfigSupport();
|
| - decoder2_->EnableEncryptedConfigSupport();
|
| - decoder3_->EnableEncryptedConfigSupport();
|
| - }
|
| -
|
| ScopedVector<VideoDecoder> decoders;
|
| - decoders.push_back(decoder1_);
|
| - decoders.push_back(decoder2_);
|
| - decoders.push_back(decoder3_);
|
| + for (int i = 0; i < 3; ++i) {
|
| + FakeVideoDecoder* decoder =
|
| + new FakeVideoDecoder(GetDecoderName(i), decoding_delay,
|
| + parallel_decoding, bytes_decoded_cb);
|
| +
|
| + if (GetParam().is_encrypted && !GetParam().has_decryptor)
|
| + decoder->EnableEncryptedConfigSupport();
|
| +
|
| + decoders.push_back(decoder);
|
| +
|
| + // Keep a copy of the raw pointers so we can change the behavior of each
|
| + // decoder.
|
| + decoders_.push_back(decoder);
|
| + }
|
|
|
| video_frame_stream_.reset(new VideoFrameStream(
|
| message_loop_.task_runner(), std::move(decoders), &media_log_));
|
|
|
| + video_frame_stream_->set_decoder_change_observer_for_testing(base::Bind(
|
| + &VideoFrameStreamTest::OnDecoderChanged, base::Unretained(this)));
|
| +
|
| if (GetParam().is_encrypted && GetParam().has_decryptor) {
|
| decryptor_.reset(new NiceMock<MockDecryptor>());
|
|
|
| @@ -118,9 +125,7 @@ class VideoFrameStreamTest
|
| EXPECT_EQ(num_decoded_bytes_unreported_, 0);
|
|
|
| is_initialized_ = false;
|
| - decoder1_ = NULL;
|
| - decoder2_ = NULL;
|
| - decoder3_ = NULL;
|
| + decoders_.clear();
|
| video_frame_stream_.reset();
|
| base::RunLoop().RunUntilIdle();
|
|
|
| @@ -140,6 +145,11 @@ class VideoFrameStreamTest
|
| num_decoded_bytes_unreported_ += count;
|
| }
|
|
|
| + void SimulateDecoderInitFailure(const std::vector<int>& decoder_indices) {
|
| + for (const auto& i : decoder_indices)
|
| + decoders_[i]->SimulateFailureToInit();
|
| + }
|
| +
|
| void OnInitialized(bool success) {
|
| DCHECK(!pending_read_);
|
| DCHECK(!pending_reset_);
|
| @@ -147,14 +157,11 @@ class VideoFrameStreamTest
|
| pending_initialize_ = false;
|
|
|
| is_initialized_ = success;
|
| - if (!success) {
|
| - decoder1_ = NULL;
|
| - decoder2_ = NULL;
|
| - decoder3_ = NULL;
|
| - }
|
| + if (!success)
|
| + decoders_.clear();
|
| }
|
|
|
| - void InitializeVideoFrameStream() {
|
| + void Initialize() {
|
| pending_initialize_ = true;
|
| video_frame_stream_->Initialize(
|
| demuxer_stream_.get(), base::Bind(&VideoFrameStreamTest::OnInitialized,
|
| @@ -166,6 +173,18 @@ class VideoFrameStreamTest
|
| base::RunLoop().RunUntilIdle();
|
| }
|
|
|
| + void OnDecoderChanged(VideoDecoder* decoder) {
|
| + if (!decoder) {
|
| + decoder_ = nullptr;
|
| + return;
|
| + }
|
| +
|
| + std::string name = decoder->GetDisplayName();
|
| + ASSERT_TRUE(GetDecoderName(0) == name || GetDecoderName(1) == name ||
|
| + GetDecoderName(2) == name);
|
| + decoder_ = static_cast<FakeVideoDecoder*>(decoder);
|
| + }
|
| +
|
| // Fake Decrypt() function used by DecryptingDemuxerStream. It does nothing
|
| // but removes the DecryptConfig to make the buffer unencrypted.
|
| void Decrypt(Decryptor::StreamType stream_type,
|
| @@ -240,17 +259,12 @@ class VideoFrameStreamTest
|
| DEMUXER_READ_NORMAL,
|
| DEMUXER_READ_CONFIG_CHANGE,
|
| DECRYPTOR_NO_KEY,
|
| - DECODER_INIT,
|
| DECODER_REINIT,
|
| DECODER_DECODE,
|
| DECODER_RESET
|
| };
|
|
|
| void EnterPendingState(PendingState state) {
|
| - EnterPendingState(state, decoder1_);
|
| - }
|
| -
|
| - void EnterPendingState(PendingState state, FakeVideoDecoder* decoder) {
|
| DCHECK_NE(state, NOT_PENDING);
|
| switch (state) {
|
| case DEMUXER_READ_NORMAL:
|
| @@ -271,23 +285,18 @@ class VideoFrameStreamTest
|
| ReadOneFrame();
|
| break;
|
|
|
| - case DECODER_INIT:
|
| - decoder->HoldNextInit();
|
| - InitializeVideoFrameStream();
|
| - break;
|
| -
|
| case DECODER_REINIT:
|
| - decoder->HoldNextInit();
|
| + decoder_->HoldNextInit();
|
| ReadUntilPending();
|
| break;
|
|
|
| case DECODER_DECODE:
|
| - decoder->HoldDecode();
|
| + decoder_->HoldDecode();
|
| ReadUntilPending();
|
| break;
|
|
|
| case DECODER_RESET:
|
| - decoder->HoldNextReset();
|
| + decoder_->HoldNextReset();
|
| pending_reset_ = true;
|
| video_frame_stream_->Reset(base::Bind(&VideoFrameStreamTest::OnReset,
|
| base::Unretained(this)));
|
| @@ -301,10 +310,6 @@ class VideoFrameStreamTest
|
| }
|
|
|
| void SatisfyPendingCallback(PendingState state) {
|
| - SatisfyPendingCallback(state, decoder1_);
|
| - }
|
| -
|
| - void SatisfyPendingCallback(PendingState state, FakeVideoDecoder* decoder) {
|
| DCHECK_NE(state, NOT_PENDING);
|
| switch (state) {
|
| case DEMUXER_READ_NORMAL:
|
| @@ -318,20 +323,16 @@ class VideoFrameStreamTest
|
| NOTREACHED();
|
| break;
|
|
|
| - case DECODER_INIT:
|
| - decoder->SatisfyInit();
|
| - break;
|
| -
|
| case DECODER_REINIT:
|
| - decoder->SatisfyInit();
|
| + decoder_->SatisfyInit();
|
| break;
|
|
|
| case DECODER_DECODE:
|
| - decoder->SatisfyDecode();
|
| + decoder_->SatisfyDecode();
|
| break;
|
|
|
| case DECODER_RESET:
|
| - decoder->SatisfyReset();
|
| + decoder_->SatisfyReset();
|
| break;
|
|
|
| case NOT_PENDING:
|
| @@ -342,11 +343,6 @@ class VideoFrameStreamTest
|
| base::RunLoop().RunUntilIdle();
|
| }
|
|
|
| - void Initialize() {
|
| - EnterPendingState(DECODER_INIT);
|
| - SatisfyPendingCallback(DECODER_INIT);
|
| - }
|
| -
|
| void Read() {
|
| EnterPendingState(DECODER_DECODE);
|
| SatisfyPendingCallback(DECODER_DECODE);
|
| @@ -357,9 +353,9 @@ class VideoFrameStreamTest
|
| SatisfyPendingCallback(DECODER_RESET);
|
| }
|
|
|
| - void ReadUntilDecoderReinitialized(FakeVideoDecoder* decoder) {
|
| - EnterPendingState(DECODER_REINIT, decoder);
|
| - SatisfyPendingCallback(DECODER_REINIT, decoder);
|
| + void ReadUntilDecoderReinitialized() {
|
| + EnterPendingState(DECODER_REINIT);
|
| + SatisfyPendingCallback(DECODER_REINIT);
|
| }
|
|
|
| base::MessageLoop message_loop_;
|
| @@ -373,11 +369,13 @@ class VideoFrameStreamTest
|
| // e.g. RegisterNewKeyCB().
|
| std::unique_ptr<NiceMock<MockDecryptor>> decryptor_;
|
|
|
| + // Raw pointers to the list of decoders to be select from by DecoderSelector.
|
| // Three decoders are needed to test that decoder fallback can occur more than
|
| // once on a config change. They are owned by |video_frame_stream_|.
|
| - FakeVideoDecoder* decoder1_;
|
| - FakeVideoDecoder* decoder2_;
|
| - FakeVideoDecoder* decoder3_;
|
| + std::vector<FakeVideoDecoder*> decoders_;
|
| +
|
| + // The current decoder used by |video_frame_stream_|.
|
| + FakeVideoDecoder* decoder_;
|
|
|
| bool is_initialized_;
|
| int num_decoded_frames_;
|
| @@ -425,16 +423,13 @@ TEST_P(VideoFrameStreamTest, Initialization) {
|
| }
|
|
|
| TEST_P(VideoFrameStreamTest, AllDecoderInitializationFails) {
|
| - decoder1_->SimulateFailureToInit();
|
| - decoder2_->SimulateFailureToInit();
|
| - decoder3_->SimulateFailureToInit();
|
| + SimulateDecoderInitFailure({0, 1, 2});
|
| Initialize();
|
| EXPECT_FALSE(is_initialized_);
|
| }
|
|
|
| TEST_P(VideoFrameStreamTest, PartialDecoderInitializationFails) {
|
| - decoder1_->SimulateFailureToInit();
|
| - decoder2_->SimulateFailureToInit();
|
| + SimulateDecoderInitFailure({0, 1});
|
| Initialize();
|
| EXPECT_TRUE(is_initialized_);
|
| }
|
| @@ -493,7 +488,7 @@ TEST_P(VideoFrameStreamTest, Read_BlockedDemuxerAndDecoder) {
|
|
|
| Initialize();
|
| demuxer_stream_->HoldNextRead();
|
| - decoder1_->HoldDecode();
|
| + decoder_->HoldDecode();
|
| ReadOneFrame();
|
| EXPECT_TRUE(pending_read_);
|
|
|
| @@ -508,7 +503,7 @@ TEST_P(VideoFrameStreamTest, Read_BlockedDemuxerAndDecoder) {
|
|
|
| // Always keep one decode request pending.
|
| if (demuxed_buffers > 1) {
|
| - decoder1_->SatisfySingleDecode();
|
| + decoder_->SatisfySingleDecode();
|
| base::RunLoop().RunUntilIdle();
|
| }
|
| }
|
| @@ -518,12 +513,12 @@ TEST_P(VideoFrameStreamTest, Read_BlockedDemuxerAndDecoder) {
|
|
|
| // Unblocking one decode request should unblock read even when demuxer is
|
| // still blocked.
|
| - decoder1_->SatisfySingleDecode();
|
| + decoder_->SatisfySingleDecode();
|
| base::RunLoop().RunUntilIdle();
|
| EXPECT_FALSE(pending_read_);
|
|
|
| // Stream should still be blocked on the demuxer after unblocking the decoder.
|
| - decoder1_->SatisfyDecode();
|
| + decoder_->SatisfyDecode();
|
| ReadUntilPending();
|
| EXPECT_TRUE(pending_read_);
|
|
|
| @@ -544,7 +539,7 @@ TEST_P(VideoFrameStreamTest, Read_DuringEndOfStreamDecode) {
|
| return;
|
|
|
| Initialize();
|
| - decoder1_->HoldDecode();
|
| + decoder_->HoldDecode();
|
|
|
| // Read all of the frames up to end of stream. Since parallel decoding is
|
| // enabled, the end of stream buffer will be sent to the decoder immediately,
|
| @@ -553,7 +548,7 @@ TEST_P(VideoFrameStreamTest, Read_DuringEndOfStreamDecode) {
|
| for (int frame = 0; frame < kNumBuffersInOneConfig; frame++) {
|
| ReadOneFrame();
|
| while (pending_read_) {
|
| - decoder1_->SatisfySingleDecode();
|
| + decoder_->SatisfySingleDecode();
|
| base::RunLoop().RunUntilIdle();
|
| }
|
| }
|
| @@ -564,7 +559,7 @@ TEST_P(VideoFrameStreamTest, Read_DuringEndOfStreamDecode) {
|
| ASSERT_TRUE(pending_read_);
|
|
|
| // Satisfy decoding of the end of stream buffer. The read should complete.
|
| - decoder1_->SatisfySingleDecode();
|
| + decoder_->SatisfySingleDecode();
|
| base::RunLoop().RunUntilIdle();
|
| ASSERT_FALSE(pending_read_);
|
| EXPECT_EQ(last_read_status_, VideoFrameStream::OK);
|
| @@ -665,7 +660,8 @@ TEST_P(VideoFrameStreamTest, Destroy_BeforeInitialization) {
|
| }
|
|
|
| TEST_P(VideoFrameStreamTest, Destroy_DuringInitialization) {
|
| - EnterPendingState(DECODER_INIT);
|
| + decoders_[0]->HoldNextInit();
|
| + Initialize();
|
| }
|
|
|
| TEST_P(VideoFrameStreamTest, Destroy_AfterInitialization) {
|
| @@ -748,17 +744,20 @@ TEST_P(VideoFrameStreamTest, Destroy_AfterRead_AfterReset) {
|
| Reset();
|
| }
|
|
|
| +// The following tests cover the fallback logic.
|
| +
|
| TEST_P(VideoFrameStreamTest, FallbackDecoder_SelectedOnInitialDecodeError) {
|
| Initialize();
|
| - decoder1_->SimulateError();
|
| + decoder_->SimulateError();
|
| ReadOneFrame();
|
|
|
| - // |video_frame_stream_| should have fallen back to |decoder2_|.
|
| + // |video_frame_stream_| should have fallen back to a new decoder.
|
| + ASSERT_EQ(GetDecoderName(1), decoder_->GetDisplayName());
|
| ASSERT_FALSE(pending_read_);
|
| ASSERT_EQ(VideoFrameStream::OK, last_read_status_);
|
|
|
| - // Can't check |decoder1_| right now, it might have been destroyed already.
|
| - ASSERT_GT(decoder2_->total_bytes_decoded(), 0);
|
| + // Check that we fallbacked to Decoder2.
|
| + ASSERT_GT(decoder_->total_bytes_decoded(), 0);
|
|
|
| // Verify no frame was dropped.
|
| ReadAllFrames();
|
| @@ -771,14 +770,14 @@ TEST_P(VideoFrameStreamTest, FallbackDecoder_EndOfStreamReachedBeforeFallback) {
|
| return;
|
|
|
| Initialize();
|
| - decoder1_->HoldDecode();
|
| + decoder_->HoldDecode();
|
| ReadOneFrame();
|
|
|
| // One buffer should have already pulled from the demuxer stream. Set the next
|
| // one to be an EOS.
|
| demuxer_stream_->SeekToEndOfStream();
|
|
|
| - decoder1_->SatisfySingleDecode();
|
| + decoder_->SatisfySingleDecode();
|
| base::RunLoop().RunUntilIdle();
|
|
|
| // |video_frame_stream_| should not have emited a frame.
|
| @@ -787,15 +786,17 @@ TEST_P(VideoFrameStreamTest, FallbackDecoder_EndOfStreamReachedBeforeFallback) {
|
| // Pending buffers should contain a regular buffer and an EOS buffer.
|
| EXPECT_EQ(video_frame_stream_->get_pending_buffers_size_for_testing(), 2);
|
|
|
| - decoder1_->SimulateError();
|
| + decoder_->SimulateError();
|
| base::RunLoop().RunUntilIdle();
|
|
|
| - // A frame should have been emited
|
| + ASSERT_EQ(GetDecoderName(1), decoder_->GetDisplayName());
|
| +
|
| + // A frame should have been emitted.
|
| EXPECT_FALSE(pending_read_);
|
| EXPECT_EQ(last_read_status_, VideoFrameStream::OK);
|
| EXPECT_FALSE(
|
| frame_read_->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM));
|
| - EXPECT_GT(decoder2_->total_bytes_decoded(), 0);
|
| + EXPECT_GT(decoder_->total_bytes_decoded(), 0);
|
|
|
| ReadOneFrame();
|
|
|
| @@ -811,7 +812,7 @@ TEST_P(VideoFrameStreamTest, FallbackDecoder_DoesReinitializeStompPendingRead) {
|
| return;
|
|
|
| Initialize();
|
| - decoder1_->HoldDecode();
|
| + decoder_->HoldDecode();
|
|
|
| // Queue one read, defer the second.
|
| frame_read_ = nullptr;
|
| @@ -822,43 +823,48 @@ TEST_P(VideoFrameStreamTest, FallbackDecoder_DoesReinitializeStompPendingRead) {
|
|
|
| // Force an error to occur on the first decode, but ensure it isn't propagated
|
| // until after the next read has been started.
|
| - decoder1_->SimulateError();
|
| - decoder2_->HoldDecode();
|
| + decoder_->SimulateError();
|
| + decoders_[1]->HoldDecode();
|
|
|
| // Complete the fallback to the second decoder with the read still pending.
|
| base::RunLoop().RunUntilIdle();
|
|
|
| - // Can't check |decoder1_| right now, it might have been destroyed already.
|
| - // Verify that there was nothing decoded until we kicked the decoder.
|
| - EXPECT_EQ(decoder2_->total_bytes_decoded(), 0);
|
| - decoder2_->SatisfyDecode();
|
| - const int first_decoded_bytes = decoder2_->total_bytes_decoded();
|
| + ASSERT_EQ(GetDecoderName(1), decoder_->GetDisplayName());
|
| +
|
| + // Can't check the original decoder right now, it might have been destroyed
|
| + // already. Verify that there was nothing decoded until we kicked the decoder.
|
| + EXPECT_EQ(decoder_->total_bytes_decoded(), 0);
|
| + decoder_->SatisfyDecode();
|
| + const int first_decoded_bytes = decoder_->total_bytes_decoded();
|
| ASSERT_GT(first_decoded_bytes, 0);
|
|
|
| // Satisfy the previously pending read and ensure it is decoded.
|
| demuxer_stream_->SatisfyRead();
|
| base::RunLoop().RunUntilIdle();
|
| - ASSERT_GT(decoder2_->total_bytes_decoded(), first_decoded_bytes);
|
| + ASSERT_GT(decoder_->total_bytes_decoded(), first_decoded_bytes);
|
| }
|
|
|
| TEST_P(VideoFrameStreamTest,
|
| FallbackDecoder_SelectedOnInitialDecodeError_Twice) {
|
| Initialize();
|
| - decoder1_->SimulateError();
|
| - decoder2_->HoldNextInit();
|
| + decoder_->SimulateError();
|
| +
|
| + decoders_[1]->HoldNextInit();
|
| ReadOneFrame();
|
|
|
| - decoder2_->SatisfyInit();
|
| - decoder2_->SimulateError();
|
| + decoders_[1]->SatisfyInit();
|
| + decoders_[1]->SimulateError();
|
| base::RunLoop().RunUntilIdle();
|
|
|
| - // |video_frame_stream_| should have fallen back to |decoder3_|.
|
| + ASSERT_EQ(GetDecoderName(2), decoder_->GetDisplayName());
|
| +
|
| + // |video_frame_stream_| should have fallen back to |decoders_[2]|.
|
| ASSERT_FALSE(pending_read_);
|
| ASSERT_EQ(VideoFrameStream::OK, last_read_status_);
|
|
|
| - // Can't check |decoder1_| or |decoder2_| right now, they might have been
|
| + // Can't check previously selected decoder(s) right now, they might have been
|
| // destroyed already.
|
| - ASSERT_GT(decoder3_->total_bytes_decoded(), 0);
|
| + ASSERT_GT(decoder_->total_bytes_decoded(), 0);
|
|
|
| // Verify no frame was dropped.
|
| ReadAllFrames();
|
| @@ -891,20 +897,20 @@ TEST_P(VideoFrameStreamTest, FallbackDecoder_ErrorDuringConfigChangeFlushing) {
|
| EnterPendingState(DEMUXER_READ_CONFIG_CHANGE);
|
| EXPECT_GT(video_frame_stream_->get_pending_buffers_size_for_testing(), 0);
|
|
|
| - decoder1_->HoldDecode();
|
| + decoder_->HoldDecode();
|
| SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE);
|
|
|
| // The flush request should have been sent and held.
|
| EXPECT_EQ(video_frame_stream_->get_pending_buffers_size_for_testing(), 0);
|
| EXPECT_TRUE(pending_read_);
|
|
|
| - // Triggering an error here will cause the frames in |decoder1_| to be lost.
|
| - // There are no pending buffers buffers to give to give to |decoder2_| due to
|
| - // crbug.com/603713.
|
| - decoder1_->SimulateError();
|
| + // Triggering an error here will cause the frames in selected decoder to be
|
| + // lost. There are no pending buffers to give to |decoders_[1]| due to
|
| + // http://crbug.com/603713
|
| + decoder_->SimulateError();
|
| base::RunLoop().RunUntilIdle();
|
|
|
| - // We want to make sure that |decoder2_| can decode the rest of the frames
|
| + // We want to make sure the fallback decoder can decode the rest of the frames
|
| // in the demuxer stream.
|
| ReadAllFrames(kNumBuffersInOneConfig * (kNumConfigs - 1));
|
| }
|
| @@ -923,7 +929,7 @@ TEST_P(VideoFrameStreamTest, FallbackDecoder_PendingBuffersIsFilledAndCleared) {
|
|
|
| // Block on demuxer read and decoder decode so we can step through.
|
| demuxer_stream_->HoldNextRead();
|
| - decoder1_->HoldDecode();
|
| + decoder_->HoldDecode();
|
| ReadOneFrame();
|
|
|
| int demuxer_reads_satisfied = 0;
|
| @@ -936,7 +942,7 @@ TEST_P(VideoFrameStreamTest, FallbackDecoder_PendingBuffersIsFilledAndCleared) {
|
| ++demuxer_reads_satisfied;
|
|
|
| // Decode one buffer.
|
| - decoder1_->SatisfySingleDecode();
|
| + decoder_->SatisfySingleDecode();
|
| base::RunLoop().RunUntilIdle();
|
| EXPECT_TRUE(pending_read_);
|
| EXPECT_EQ(demuxer_reads_satisfied,
|
| @@ -948,18 +954,21 @@ TEST_P(VideoFrameStreamTest, FallbackDecoder_PendingBuffersIsFilledAndCleared) {
|
| // Hold the init before triggering the error, to verify internal state.
|
| demuxer_stream_->SatisfyReadAndHoldNext();
|
| ++demuxer_reads_satisfied;
|
| - decoder2_->HoldNextInit();
|
| - decoder1_->SimulateError();
|
| +
|
| + decoder_->SimulateError();
|
| + decoders_[1]->HoldNextInit();
|
| base::RunLoop().RunUntilIdle();
|
|
|
| EXPECT_TRUE(pending_read_);
|
| EXPECT_EQ(demuxer_reads_satisfied,
|
| video_frame_stream_->get_pending_buffers_size_for_testing());
|
|
|
| - decoder2_->SatisfyInit();
|
| - decoder2_->HoldDecode();
|
| + decoders_[1]->SatisfyInit();
|
| + decoders_[1]->HoldDecode();
|
| base::RunLoop().RunUntilIdle();
|
|
|
| + ASSERT_EQ(GetDecoderName(1), decoder_->GetDisplayName());
|
| +
|
| // Make sure the pending buffers have been transfered to fallback buffers.
|
| // One call to Decode() during the initialization process, so we expect one
|
| // buffer to already have been consumed from the fallback buffers.
|
| @@ -969,11 +978,11 @@ TEST_P(VideoFrameStreamTest, FallbackDecoder_PendingBuffersIsFilledAndCleared) {
|
| EXPECT_EQ(demuxer_reads_satisfied,
|
| video_frame_stream_->get_pending_buffers_size_for_testing());
|
|
|
| - decoder2_->SatisfyDecode();
|
| + decoder_->SatisfyDecode();
|
| base::RunLoop().RunUntilIdle();
|
|
|
| - // Make sure all buffers consumed by |decoder2_| have come from the fallback.
|
| - // Pending buffers should not have been cleared yet.
|
| + // Make sure all buffers consumed by |decoders_[1]| have come from the
|
| + // fallback. Pending buffers should not have been cleared yet.
|
| EXPECT_EQ(0, video_frame_stream_->get_fallback_buffers_size_for_testing());
|
| EXPECT_EQ(demuxer_reads_satisfied,
|
| video_frame_stream_->get_pending_buffers_size_for_testing());
|
| @@ -995,37 +1004,43 @@ TEST_P(VideoFrameStreamTest, FallbackDecoder_PendingBuffersIsFilledAndCleared) {
|
|
|
| TEST_P(VideoFrameStreamTest, FallbackDecoder_SelectedOnDecodeThenInitErrors) {
|
| Initialize();
|
| - decoder1_->SimulateError();
|
| - decoder2_->SimulateFailureToInit();
|
| + decoder_->SimulateError();
|
| + SimulateDecoderInitFailure({1});
|
| ReadOneFrame();
|
|
|
| - // |video_frame_stream_| should have fallen back to |decoder3_|
|
| + ASSERT_EQ(GetDecoderName(2), decoder_->GetDisplayName());
|
| +
|
| + // |video_frame_stream_| should have fallen back to |decoders_[2]|
|
| ASSERT_FALSE(pending_read_);
|
| ASSERT_EQ(VideoFrameStream::OK, last_read_status_);
|
|
|
| - // Can't check |decoder1_| or |decoder2_| right now, they might have been
|
| + // Can't check previously selected decoder(s) right now, they might have been
|
| // destroyed already.
|
| - ASSERT_GT(decoder3_->total_bytes_decoded(), 0);
|
| + ASSERT_GT(decoder_->total_bytes_decoded(), 0);
|
|
|
| // Verify no frame was dropped.
|
| ReadAllFrames();
|
| }
|
|
|
| TEST_P(VideoFrameStreamTest, FallbackDecoder_SelectedOnInitThenDecodeErrors) {
|
| - decoder1_->SimulateFailureToInit();
|
| - decoder2_->HoldDecode();
|
| + SimulateDecoderInitFailure({0});
|
| Initialize();
|
| + ASSERT_EQ(GetDecoderName(1), decoder_->GetDisplayName());
|
| +
|
| + decoder_->HoldDecode();
|
| ReadOneFrame();
|
| - decoder2_->SimulateError();
|
| + decoder_->SimulateError();
|
| base::RunLoop().RunUntilIdle();
|
|
|
| - // |video_frame_stream_| should have fallen back to |decoder3_|
|
| + // |video_frame_stream_| should have fallen back to |decoders_[2]|
|
| + ASSERT_EQ(GetDecoderName(2), decoder_->GetDisplayName());
|
| +
|
| ASSERT_FALSE(pending_read_);
|
| ASSERT_EQ(VideoFrameStream::OK, last_read_status_);
|
|
|
| - // Can't check |decoder1_| or |decoder2_| right now, they might have been
|
| + // Can't check previously selected decoder(s) right now, they might have been
|
| // destroyed already.
|
| - ASSERT_GT(decoder3_->total_bytes_decoded(), 0);
|
| + ASSERT_GT(decoder_->total_bytes_decoded(), 0);
|
|
|
| // Verify no frame was dropped.
|
| ReadAllFrames();
|
| @@ -1038,9 +1053,9 @@ TEST_P(VideoFrameStreamTest,
|
|
|
| // Successfully received a frame.
|
| EXPECT_FALSE(pending_read_);
|
| - ASSERT_GT(decoder1_->total_bytes_decoded(), 0);
|
| + ASSERT_GT(decoder_->total_bytes_decoded(), 0);
|
|
|
| - decoder1_->SimulateError();
|
| + decoder_->SimulateError();
|
|
|
| // The error must surface from Read() as DECODE_ERROR.
|
| while (last_read_status_ == VideoFrameStream::OK) {
|
| @@ -1049,26 +1064,26 @@ TEST_P(VideoFrameStreamTest,
|
| EXPECT_FALSE(pending_read_);
|
| }
|
|
|
| - // Verify the error was surfaced, rather than falling back to |decoder2_|.
|
| + // Verify the error was surfaced, rather than falling back to other decoders.
|
| + ASSERT_EQ(GetDecoderName(0), decoder_->GetDisplayName());
|
| EXPECT_FALSE(pending_read_);
|
| - ASSERT_EQ(decoder2_->total_bytes_decoded(), 0);
|
| ASSERT_EQ(VideoFrameStream::DECODE_ERROR, last_read_status_);
|
| }
|
|
|
| TEST_P(VideoFrameStreamTest, DecoderErrorWhenNotReading) {
|
| Initialize();
|
| - decoder1_->HoldDecode();
|
| + decoder_->HoldDecode();
|
| ReadOneFrame();
|
| EXPECT_TRUE(pending_read_);
|
|
|
| // Satisfy decode requests until we get the first frame out.
|
| while (pending_read_) {
|
| - decoder1_->SatisfySingleDecode();
|
| + decoder_->SatisfySingleDecode();
|
| base::RunLoop().RunUntilIdle();
|
| }
|
|
|
| // Trigger an error in the decoding.
|
| - decoder1_->SimulateError();
|
| + decoder_->SimulateError();
|
|
|
| // The error must surface from Read() as DECODE_ERROR.
|
| while (last_read_status_ == VideoFrameStream::OK) {
|
| @@ -1081,29 +1096,31 @@ TEST_P(VideoFrameStreamTest, DecoderErrorWhenNotReading) {
|
|
|
| TEST_P(VideoFrameStreamTest, FallbackDecoderSelectedOnFailureToReinitialize) {
|
| Initialize();
|
| - decoder1_->SimulateFailureToInit();
|
| - ReadUntilDecoderReinitialized(decoder1_);
|
| + decoder_->SimulateFailureToInit();
|
| + ReadUntilDecoderReinitialized();
|
| + ASSERT_EQ(GetDecoderName(1), decoder_->GetDisplayName());
|
| ReadAllFrames();
|
| - ASSERT_GT(decoder2_->total_bytes_decoded(), 0);
|
| + ASSERT_GT(decoder_->total_bytes_decoded(), 0);
|
| }
|
|
|
| TEST_P(VideoFrameStreamTest,
|
| FallbackDecoderSelectedOnFailureToReinitialize_Twice) {
|
| Initialize();
|
| - decoder1_->SimulateFailureToInit();
|
| - ReadUntilDecoderReinitialized(decoder1_);
|
| + decoder_->SimulateFailureToInit();
|
| + ReadUntilDecoderReinitialized();
|
| + ASSERT_EQ(GetDecoderName(1), decoder_->GetDisplayName());
|
| ReadOneFrame();
|
| - decoder2_->SimulateFailureToInit();
|
| - ReadUntilDecoderReinitialized(decoder2_);
|
| + decoder_->SimulateFailureToInit();
|
| + ReadUntilDecoderReinitialized();
|
| + ASSERT_EQ(GetDecoderName(2), decoder_->GetDisplayName());
|
| ReadAllFrames();
|
| }
|
|
|
| TEST_P(VideoFrameStreamTest, DecodeErrorAfterFallbackDecoderSelectionFails) {
|
| Initialize();
|
| - decoder1_->SimulateFailureToInit();
|
| - decoder2_->SimulateFailureToInit();
|
| - decoder3_->SimulateFailureToInit();
|
| - ReadUntilDecoderReinitialized(decoder1_);
|
| + decoder_->SimulateFailureToInit();
|
| + SimulateDecoderInitFailure({1, 2});
|
| + ReadUntilDecoderReinitialized();
|
| // The error will surface from Read() as DECODE_ERROR.
|
| while (last_read_status_ == VideoFrameStream::OK) {
|
| ReadOneFrame();
|
| @@ -1115,9 +1132,9 @@ TEST_P(VideoFrameStreamTest, DecodeErrorAfterFallbackDecoderSelectionFails) {
|
|
|
| TEST_P(VideoFrameStreamTest, Destroy_DuringFallbackDecoderSelection) {
|
| Initialize();
|
| - decoder1_->SimulateFailureToInit();
|
| + decoder_->SimulateFailureToInit();
|
| EnterPendingState(DECODER_REINIT);
|
| - decoder2_->HoldNextInit();
|
| + decoders_[1]->HoldNextInit();
|
| SatisfyPendingCallback(DECODER_REINIT);
|
| }
|
|
|
|
|