From 6c0f2bebef8f0c951422ddec8828c56d40762b23 Mon Sep 17 00:00:00 2001 From: Aaron Vaage Date: Tue, 26 Sep 2017 09:00:33 -0700 Subject: [PATCH] Use TrickPlay Test Structure As Common Test Structure Took the test structure for trick play and made a common test structure that can be used for new tests. The next tests to use this structure will be the new WebVtt pipeline. Change-Id: I5faca306b8a2bd16b9f945d1ff5c336aed82bc35 --- .../media/base/media_handler_test_base.cc | 65 +++++++++ packager/media/base/media_handler_test_base.h | 18 +++ .../trick_play/trick_play_handler_unittest.cc | 137 +++++++++--------- 3 files changed, 155 insertions(+), 65 deletions(-) diff --git a/packager/media/base/media_handler_test_base.cc b/packager/media/base/media_handler_test_base.cc index 6cdac9b491..c2ff0aec50 100644 --- a/packager/media/base/media_handler_test_base.cc +++ b/packager/media/base/media_handler_test_base.cc @@ -206,6 +206,71 @@ std::unique_ptr MediaHandlerTestBase::GetTextSample( return sample; } + +Status MediaHandlerTestBase::SetUpAndInitializeGraph( + std::shared_ptr handler, + size_t input_count, + size_t output_count) { + DCHECK(handler); + DCHECK_EQ(nullptr, handler_); + DCHECK(inputs_.empty()); + DCHECK(outputs_.empty()); + + handler_ = std::move(handler); + + Status status; + + // Add and connect all the requested inputs. + for (size_t i = 0; i < input_count; i++) { + inputs_.emplace_back(new FakeInputMediaHandler); + } + + for (auto& input : inputs_) { + status.Update(input->AddHandler(handler_)); + } + + if (!status.ok()) { + return status; + } + + // Add and connect all the requested outputs. + for (size_t i = 0; i < output_count; i++) { + outputs_.emplace_back(new MockOutputMediaHandler); + } + + for (auto& output : outputs_) { + status.Update(handler_->AddHandler(output)); + } + + if (!status.ok()) { + return status; + } + + // Initialize the graph. + for (auto& input : inputs_) { + status.Update(input->Initialize()); + } + + // In the case that there are no inputs, the start of the graph + // is at |handler_| so it needs to be initialized or else the graph + // won't be initialized. + if (inputs_.empty()) { + status.Update(handler_->Initialize()); + } + + return status; +} + +FakeInputMediaHandler* MediaHandlerTestBase::Input(size_t index) { + DCHECK_LT(index, inputs_.size()); + return inputs_[index].get(); +} + +MockOutputMediaHandler* MediaHandlerTestBase::Output(size_t index) { + DCHECK_LT(index, outputs_.size()); + return outputs_[index].get(); +} + MediaHandlerGraphTestBase::MediaHandlerGraphTestBase() : next_handler_(new FakeMediaHandler), some_handler_(new FakeMediaHandler) {} diff --git a/packager/media/base/media_handler_test_base.h b/packager/media/base/media_handler_test_base.h index db1ae07b17..5a21367d9d 100644 --- a/packager/media/base/media_handler_test_base.h +++ b/packager/media/base/media_handler_test_base.h @@ -171,9 +171,27 @@ class MediaHandlerTestBase : public ::testing::Test { uint64_t end, const std::string& payload) const; + // Connect and initialize all handlers. + Status SetUpAndInitializeGraph(std::shared_ptr handler, + size_t input_count, + size_t output_count); + + // Get the input handler at |index|. The values of |index| will match the + // call to |AddInput|. + FakeInputMediaHandler* Input(size_t index); + + // Get the output handler at |index|. The values of |index| will match the + // call to |AddOutput|. + MockOutputMediaHandler* Output(size_t index); + private: MediaHandlerTestBase(const MediaHandlerTestBase&) = delete; MediaHandlerTestBase& operator=(const MediaHandlerTestBase&) = delete; + + std::shared_ptr handler_; + + std::vector> inputs_; + std::vector> outputs_; }; class MediaHandlerGraphTestBase : public MediaHandlerTestBase { diff --git a/packager/media/trick_play/trick_play_handler_unittest.cc b/packager/media/trick_play/trick_play_handler_unittest.cc index f13dcfeb6f..3c3af66a04 100644 --- a/packager/media/trick_play/trick_play_handler_unittest.cc +++ b/packager/media/trick_play/trick_play_handler_unittest.cc @@ -17,6 +17,10 @@ namespace shaka { namespace media { namespace { +const size_t kInputCount = 1; +const size_t kOutputCount = 1; +const size_t kInputIndex = 0; +const size_t kOutputIndex = 0; const size_t kStreamIndex = 0; // This value does not matter as trick play does not use it, but it is needed @@ -46,24 +50,15 @@ MATCHER_P2(IsTrickPlaySample, timestamp, duration, "") { arg->media_sample->is_key_frame(); } -// Creates a structure of [input]->[trick play]->[output] where all -// interactions are with input and output. class TrickPlayHandlerTest : public MediaHandlerTestBase { protected: void SetUpAndInitializeGraph(uint32_t factor) { - input_ = std::make_shared(); - trick_play_ = std::make_shared(factor); - output_ = std::make_shared(); - - ASSERT_OK(input_->AddHandler(trick_play_)); - ASSERT_OK(trick_play_->AddHandler(output_)); - - ASSERT_OK(input_->Initialize()); + ASSERT_OK(MediaHandlerTestBase::SetUpAndInitializeGraph( + std::make_shared(factor), + kInputCount, + kOutputCount)); } - FakeInputMediaHandler* input() { return input_.get(); } - MockOutputMediaHandler* output() { return output_.get(); } - // Create a series of samples where each sample has the same duration and ever // sample that is an even multiple of |key_frame_frequency| will be a key // frame. @@ -84,11 +79,6 @@ class TrickPlayHandlerTest : public MediaHandlerTestBase { return samples; } - - private: - std::shared_ptr input_; - std::shared_ptr trick_play_; - std::shared_ptr output_; }; // This test makes sure that audio streams are rejected by trick play handlers. @@ -96,8 +86,9 @@ TEST_F(TrickPlayHandlerTest, RejectsAudio) { const uint32_t kTrickPlayFactor = 1u; SetUpAndInitializeGraph(kTrickPlayFactor); - Status status = input()->Dispatch( - StreamData::FromStreamInfo(kStreamIndex, GetAudioStreamInfo(kTimescale))); + Status status = Input(kInputIndex) + ->Dispatch(StreamData::FromStreamInfo( + kStreamIndex, GetAudioStreamInfo(kTimescale))); EXPECT_EQ(error::TRICK_PLAY_ERROR, status.error_code()); } @@ -114,14 +105,15 @@ TEST_F(TrickPlayHandlerTest, TrickTrackNoSamples) { { testing::InSequence s; - EXPECT_CALL(*output(), + EXPECT_CALL(*Output(kOutputIndex), OnProcess(IsTrickPlayVideoStream(kTrickPlayFactor, kPlayRate))); - EXPECT_CALL(*output(), OnFlush(kStreamIndex)); + EXPECT_CALL(*Output(kOutputIndex), OnFlush(kStreamIndex)); } - ASSERT_OK(input()->Dispatch(StreamData::FromStreamInfo( - kStreamIndex, GetVideoStreamInfo(kTimescale)))); - ASSERT_OK(input()->FlushAllDownstreams()); + ASSERT_OK(Input(kInputIndex) + ->Dispatch(StreamData::FromStreamInfo( + kStreamIndex, GetVideoStreamInfo(kTimescale)))); + ASSERT_OK(Input(kInputIndex)->FlushAllDownstreams()); } // This test makes sure that when the trick play handler is initialized using @@ -142,28 +134,31 @@ TEST_F(TrickPlayHandlerTest, TrickTrackWithSamplesOnlyGetsKeyFrames) { // handler. { testing::InSequence s; - EXPECT_CALL(*output(), + EXPECT_CALL(*Output(kOutputIndex), OnProcess(IsTrickPlayVideoStream(kTrickPlayFactor, kPlayRate))); for (int i = 0; i < 3; i++) { - EXPECT_CALL(*output(), OnProcess(IsTrickPlaySample( - kStartTime + i * kTrickPlaySampleDuration, - kTrickPlaySampleDuration))); + EXPECT_CALL( + *Output(kOutputIndex), + OnProcess(IsTrickPlaySample(kStartTime + i * kTrickPlaySampleDuration, + kTrickPlaySampleDuration))); } - EXPECT_CALL(*output(), OnFlush(kStreamIndex)); + EXPECT_CALL(*Output(kOutputIndex), OnFlush(kStreamIndex)); } std::vector> samples = CreateSamples(9 /* sample count */, kStartTime, kDuration, kKeyFrameRate); - ASSERT_OK(input()->Dispatch(StreamData::FromStreamInfo( - kStreamIndex, GetVideoStreamInfo(kTimescale)))); + ASSERT_OK(Input(kInputIndex) + ->Dispatch(StreamData::FromStreamInfo( + kStreamIndex, GetVideoStreamInfo(kTimescale)))); for (const auto& sample : samples) { ASSERT_OK( - input()->Dispatch(StreamData::FromMediaSample(kStreamIndex, sample))); + Input(kInputIndex) + ->Dispatch(StreamData::FromMediaSample(kStreamIndex, sample))); } - ASSERT_OK(input()->FlushAllDownstreams()); + ASSERT_OK(Input(kInputIndex)->FlushAllDownstreams()); } // This test makes sure that when the trick play handler is initialized using @@ -184,28 +179,31 @@ TEST_F(TrickPlayHandlerTest, TrickTrackWithSamples) { // handler. { testing::InSequence s; - EXPECT_CALL(*output(), + EXPECT_CALL(*Output(kOutputIndex), OnProcess(IsTrickPlayVideoStream(kTrickPlayFactor, kPlayRate))); for (int i = 0; i < 2; i++) { - EXPECT_CALL(*output(), OnProcess(IsTrickPlaySample( - kStartTime + i * kTrickPlaySampleDuration, - kTrickPlaySampleDuration))); + EXPECT_CALL( + *Output(kOutputIndex), + OnProcess(IsTrickPlaySample(kStartTime + i * kTrickPlaySampleDuration, + kTrickPlaySampleDuration))); } - EXPECT_CALL(*output(), OnFlush(0u)); + EXPECT_CALL(*Output(kOutputIndex), OnFlush(0u)); } std::vector> samples = CreateSamples(8 /* sample count */, kStartTime, kDuration, kKeyFrameRate); - ASSERT_OK(input()->Dispatch(StreamData::FromStreamInfo( - kStreamIndex, GetVideoStreamInfo(kTimescale)))); + ASSERT_OK(Input(kInputIndex) + ->Dispatch(StreamData::FromStreamInfo( + kStreamIndex, GetVideoStreamInfo(kTimescale)))); for (const auto& sample : samples) { ASSERT_OK( - input()->Dispatch(StreamData::FromMediaSample(kStreamIndex, sample))); + Input(kInputIndex) + ->Dispatch(StreamData::FromMediaSample(kStreamIndex, sample))); } - ASSERT_OK(input()->FlushAllDownstreams()); + ASSERT_OK(Input(kInputIndex)->FlushAllDownstreams()); } TEST_F(TrickPlayHandlerTest, TrickTrackWithSamplesAndSegments) { @@ -223,30 +221,33 @@ TEST_F(TrickPlayHandlerTest, TrickTrackWithSamplesAndSegments) { // handler. { testing::InSequence s; - EXPECT_CALL(*output(), + EXPECT_CALL(*Output(kOutputIndex), OnProcess(IsTrickPlayVideoStream(kTrickPlayFactor, kPlayRate))); // Segment One for (int i = 0; i < 2; i++) { - EXPECT_CALL(*output(), OnProcess(IsTrickPlaySample( - kStartTime + kTrickPlaySampleDuration * i, - kTrickPlaySampleDuration))); + EXPECT_CALL( + *Output(kOutputIndex), + OnProcess(IsTrickPlaySample(kStartTime + kTrickPlaySampleDuration * i, + kTrickPlaySampleDuration))); } - EXPECT_CALL(*output(), + EXPECT_CALL(*Output(kOutputIndex), OnProcess(IsSegmentInfo(kStreamIndex, kStartTime, 4 * kDuration, !kSubSegment, !kEncrypted))); // Segment Two for (int i = 2; i < 4; i++) { - EXPECT_CALL(*output(), OnProcess(IsTrickPlaySample( - kStartTime + kTrickPlaySampleDuration * i, - kTrickPlaySampleDuration))); + EXPECT_CALL( + *Output(kOutputIndex), + OnProcess(IsTrickPlaySample(kStartTime + kTrickPlaySampleDuration * i, + kTrickPlaySampleDuration))); } - EXPECT_CALL(*output(), OnProcess(IsSegmentInfo( - kStreamIndex, kStartTime + 4 * kDuration, - 4 * kDuration, !kSubSegment, !kEncrypted))); + EXPECT_CALL( + *Output(kOutputIndex), + OnProcess(IsSegmentInfo(kStreamIndex, kStartTime + 4 * kDuration, + 4 * kDuration, !kSubSegment, !kEncrypted))); - EXPECT_CALL(*output(), OnFlush(0u)); + EXPECT_CALL(*Output(kOutputIndex), OnFlush(0u)); } std::vector> segment_one_samples = @@ -256,27 +257,33 @@ TEST_F(TrickPlayHandlerTest, TrickTrackWithSamplesAndSegments) { CreateSamples(4 /* sample count */, kStartTime + 4 * kDuration, kDuration, kKeyFrameRate); - ASSERT_OK(input()->Dispatch(StreamData::FromStreamInfo( - kStreamIndex, GetVideoStreamInfo(kTimescale)))); + ASSERT_OK(Input(kInputIndex) + ->Dispatch(StreamData::FromStreamInfo( + kStreamIndex, GetVideoStreamInfo(kTimescale)))); // Segment One for (const auto& sample : segment_one_samples) { ASSERT_OK( - input()->Dispatch(StreamData::FromMediaSample(kStreamIndex, sample))); + Input(kInputIndex) + ->Dispatch(StreamData::FromMediaSample(kStreamIndex, sample))); } - ASSERT_OK(input()->Dispatch(StreamData::FromSegmentInfo( - kStreamIndex, GetSegmentInfo(kStartTime, kDuration * 4, !kEncrypted)))); + ASSERT_OK(Input(kInputIndex) + ->Dispatch(StreamData::FromSegmentInfo( + kStreamIndex, + GetSegmentInfo(kStartTime, kDuration * 4, !kEncrypted)))); // Segment Two for (const auto& sample : segment_two_samples) { ASSERT_OK( - input()->Dispatch(StreamData::FromMediaSample(kStreamIndex, sample))); + Input(kInputIndex) + ->Dispatch(StreamData::FromMediaSample(kStreamIndex, sample))); } - ASSERT_OK(input()->Dispatch(StreamData::FromSegmentInfo( - kStreamIndex, - GetSegmentInfo(kStartTime + 4 * kDuration, 4 * kDuration, !kEncrypted)))); + ASSERT_OK(Input(kInputIndex) + ->Dispatch(StreamData::FromSegmentInfo( + kStreamIndex, GetSegmentInfo(kStartTime + 4 * kDuration, + 4 * kDuration, !kEncrypted)))); - ASSERT_OK(input()->FlushAllDownstreams()); + ASSERT_OK(Input(kInputIndex)->FlushAllDownstreams()); } } // namespace media