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
This commit is contained in:
parent
9cb4018235
commit
6c0f2bebef
|
@ -206,6 +206,71 @@ std::unique_ptr<TextSample> MediaHandlerTestBase::GetTextSample(
|
||||||
|
|
||||||
return sample;
|
return sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Status MediaHandlerTestBase::SetUpAndInitializeGraph(
|
||||||
|
std::shared_ptr<MediaHandler> 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()
|
MediaHandlerGraphTestBase::MediaHandlerGraphTestBase()
|
||||||
: next_handler_(new FakeMediaHandler),
|
: next_handler_(new FakeMediaHandler),
|
||||||
some_handler_(new FakeMediaHandler) {}
|
some_handler_(new FakeMediaHandler) {}
|
||||||
|
|
|
@ -171,9 +171,27 @@ class MediaHandlerTestBase : public ::testing::Test {
|
||||||
uint64_t end,
|
uint64_t end,
|
||||||
const std::string& payload) const;
|
const std::string& payload) const;
|
||||||
|
|
||||||
|
// Connect and initialize all handlers.
|
||||||
|
Status SetUpAndInitializeGraph(std::shared_ptr<MediaHandler> 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:
|
private:
|
||||||
MediaHandlerTestBase(const MediaHandlerTestBase&) = delete;
|
MediaHandlerTestBase(const MediaHandlerTestBase&) = delete;
|
||||||
MediaHandlerTestBase& operator=(const MediaHandlerTestBase&) = delete;
|
MediaHandlerTestBase& operator=(const MediaHandlerTestBase&) = delete;
|
||||||
|
|
||||||
|
std::shared_ptr<MediaHandler> handler_;
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<FakeInputMediaHandler>> inputs_;
|
||||||
|
std::vector<std::shared_ptr<MockOutputMediaHandler>> outputs_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MediaHandlerGraphTestBase : public MediaHandlerTestBase {
|
class MediaHandlerGraphTestBase : public MediaHandlerTestBase {
|
||||||
|
|
|
@ -17,6 +17,10 @@
|
||||||
namespace shaka {
|
namespace shaka {
|
||||||
namespace media {
|
namespace media {
|
||||||
namespace {
|
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;
|
const size_t kStreamIndex = 0;
|
||||||
|
|
||||||
// This value does not matter as trick play does not use it, but it is needed
|
// 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();
|
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 {
|
class TrickPlayHandlerTest : public MediaHandlerTestBase {
|
||||||
protected:
|
protected:
|
||||||
void SetUpAndInitializeGraph(uint32_t factor) {
|
void SetUpAndInitializeGraph(uint32_t factor) {
|
||||||
input_ = std::make_shared<FakeInputMediaHandler>();
|
ASSERT_OK(MediaHandlerTestBase::SetUpAndInitializeGraph(
|
||||||
trick_play_ = std::make_shared<TrickPlayHandler>(factor);
|
std::make_shared<TrickPlayHandler>(factor),
|
||||||
output_ = std::make_shared<MockOutputMediaHandler>();
|
kInputCount,
|
||||||
|
kOutputCount));
|
||||||
ASSERT_OK(input_->AddHandler(trick_play_));
|
|
||||||
ASSERT_OK(trick_play_->AddHandler(output_));
|
|
||||||
|
|
||||||
ASSERT_OK(input_->Initialize());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FakeInputMediaHandler* input() { return input_.get(); }
|
|
||||||
MockOutputMediaHandler* output() { return output_.get(); }
|
|
||||||
|
|
||||||
// Create a series of samples where each sample has the same duration and ever
|
// 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
|
// sample that is an even multiple of |key_frame_frequency| will be a key
|
||||||
// frame.
|
// frame.
|
||||||
|
@ -84,11 +79,6 @@ class TrickPlayHandlerTest : public MediaHandlerTestBase {
|
||||||
|
|
||||||
return samples;
|
return samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
std::shared_ptr<FakeInputMediaHandler> input_;
|
|
||||||
std::shared_ptr<MediaHandler> trick_play_;
|
|
||||||
std::shared_ptr<MockOutputMediaHandler> output_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// This test makes sure that audio streams are rejected by trick play handlers.
|
// 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;
|
const uint32_t kTrickPlayFactor = 1u;
|
||||||
SetUpAndInitializeGraph(kTrickPlayFactor);
|
SetUpAndInitializeGraph(kTrickPlayFactor);
|
||||||
|
|
||||||
Status status = input()->Dispatch(
|
Status status = Input(kInputIndex)
|
||||||
StreamData::FromStreamInfo(kStreamIndex, GetAudioStreamInfo(kTimescale)));
|
->Dispatch(StreamData::FromStreamInfo(
|
||||||
|
kStreamIndex, GetAudioStreamInfo(kTimescale)));
|
||||||
EXPECT_EQ(error::TRICK_PLAY_ERROR, status.error_code());
|
EXPECT_EQ(error::TRICK_PLAY_ERROR, status.error_code());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,14 +105,15 @@ TEST_F(TrickPlayHandlerTest, TrickTrackNoSamples) {
|
||||||
|
|
||||||
{
|
{
|
||||||
testing::InSequence s;
|
testing::InSequence s;
|
||||||
EXPECT_CALL(*output(),
|
EXPECT_CALL(*Output(kOutputIndex),
|
||||||
OnProcess(IsTrickPlayVideoStream(kTrickPlayFactor, kPlayRate)));
|
OnProcess(IsTrickPlayVideoStream(kTrickPlayFactor, kPlayRate)));
|
||||||
EXPECT_CALL(*output(), OnFlush(kStreamIndex));
|
EXPECT_CALL(*Output(kOutputIndex), OnFlush(kStreamIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT_OK(input()->Dispatch(StreamData::FromStreamInfo(
|
ASSERT_OK(Input(kInputIndex)
|
||||||
|
->Dispatch(StreamData::FromStreamInfo(
|
||||||
kStreamIndex, GetVideoStreamInfo(kTimescale))));
|
kStreamIndex, GetVideoStreamInfo(kTimescale))));
|
||||||
ASSERT_OK(input()->FlushAllDownstreams());
|
ASSERT_OK(Input(kInputIndex)->FlushAllDownstreams());
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test makes sure that when the trick play handler is initialized using
|
// This test makes sure that when the trick play handler is initialized using
|
||||||
|
@ -142,28 +134,31 @@ TEST_F(TrickPlayHandlerTest, TrickTrackWithSamplesOnlyGetsKeyFrames) {
|
||||||
// handler.
|
// handler.
|
||||||
{
|
{
|
||||||
testing::InSequence s;
|
testing::InSequence s;
|
||||||
EXPECT_CALL(*output(),
|
EXPECT_CALL(*Output(kOutputIndex),
|
||||||
OnProcess(IsTrickPlayVideoStream(kTrickPlayFactor, kPlayRate)));
|
OnProcess(IsTrickPlayVideoStream(kTrickPlayFactor, kPlayRate)));
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
EXPECT_CALL(*output(), OnProcess(IsTrickPlaySample(
|
EXPECT_CALL(
|
||||||
kStartTime + i * kTrickPlaySampleDuration,
|
*Output(kOutputIndex),
|
||||||
|
OnProcess(IsTrickPlaySample(kStartTime + i * kTrickPlaySampleDuration,
|
||||||
kTrickPlaySampleDuration)));
|
kTrickPlaySampleDuration)));
|
||||||
}
|
}
|
||||||
EXPECT_CALL(*output(), OnFlush(kStreamIndex));
|
EXPECT_CALL(*Output(kOutputIndex), OnFlush(kStreamIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::shared_ptr<MediaSample>> samples =
|
std::vector<std::shared_ptr<MediaSample>> samples =
|
||||||
CreateSamples(9 /* sample count */, kStartTime, kDuration, kKeyFrameRate);
|
CreateSamples(9 /* sample count */, kStartTime, kDuration, kKeyFrameRate);
|
||||||
|
|
||||||
ASSERT_OK(input()->Dispatch(StreamData::FromStreamInfo(
|
ASSERT_OK(Input(kInputIndex)
|
||||||
|
->Dispatch(StreamData::FromStreamInfo(
|
||||||
kStreamIndex, GetVideoStreamInfo(kTimescale))));
|
kStreamIndex, GetVideoStreamInfo(kTimescale))));
|
||||||
|
|
||||||
for (const auto& sample : samples) {
|
for (const auto& sample : samples) {
|
||||||
ASSERT_OK(
|
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
|
// This test makes sure that when the trick play handler is initialized using
|
||||||
|
@ -184,28 +179,31 @@ TEST_F(TrickPlayHandlerTest, TrickTrackWithSamples) {
|
||||||
// handler.
|
// handler.
|
||||||
{
|
{
|
||||||
testing::InSequence s;
|
testing::InSequence s;
|
||||||
EXPECT_CALL(*output(),
|
EXPECT_CALL(*Output(kOutputIndex),
|
||||||
OnProcess(IsTrickPlayVideoStream(kTrickPlayFactor, kPlayRate)));
|
OnProcess(IsTrickPlayVideoStream(kTrickPlayFactor, kPlayRate)));
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
EXPECT_CALL(*output(), OnProcess(IsTrickPlaySample(
|
EXPECT_CALL(
|
||||||
kStartTime + i * kTrickPlaySampleDuration,
|
*Output(kOutputIndex),
|
||||||
|
OnProcess(IsTrickPlaySample(kStartTime + i * kTrickPlaySampleDuration,
|
||||||
kTrickPlaySampleDuration)));
|
kTrickPlaySampleDuration)));
|
||||||
}
|
}
|
||||||
EXPECT_CALL(*output(), OnFlush(0u));
|
EXPECT_CALL(*Output(kOutputIndex), OnFlush(0u));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::shared_ptr<MediaSample>> samples =
|
std::vector<std::shared_ptr<MediaSample>> samples =
|
||||||
CreateSamples(8 /* sample count */, kStartTime, kDuration, kKeyFrameRate);
|
CreateSamples(8 /* sample count */, kStartTime, kDuration, kKeyFrameRate);
|
||||||
|
|
||||||
ASSERT_OK(input()->Dispatch(StreamData::FromStreamInfo(
|
ASSERT_OK(Input(kInputIndex)
|
||||||
|
->Dispatch(StreamData::FromStreamInfo(
|
||||||
kStreamIndex, GetVideoStreamInfo(kTimescale))));
|
kStreamIndex, GetVideoStreamInfo(kTimescale))));
|
||||||
|
|
||||||
for (const auto& sample : samples) {
|
for (const auto& sample : samples) {
|
||||||
ASSERT_OK(
|
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) {
|
TEST_F(TrickPlayHandlerTest, TrickTrackWithSamplesAndSegments) {
|
||||||
|
@ -223,30 +221,33 @@ TEST_F(TrickPlayHandlerTest, TrickTrackWithSamplesAndSegments) {
|
||||||
// handler.
|
// handler.
|
||||||
{
|
{
|
||||||
testing::InSequence s;
|
testing::InSequence s;
|
||||||
EXPECT_CALL(*output(),
|
EXPECT_CALL(*Output(kOutputIndex),
|
||||||
OnProcess(IsTrickPlayVideoStream(kTrickPlayFactor, kPlayRate)));
|
OnProcess(IsTrickPlayVideoStream(kTrickPlayFactor, kPlayRate)));
|
||||||
|
|
||||||
// Segment One
|
// Segment One
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
EXPECT_CALL(*output(), OnProcess(IsTrickPlaySample(
|
EXPECT_CALL(
|
||||||
kStartTime + kTrickPlaySampleDuration * i,
|
*Output(kOutputIndex),
|
||||||
|
OnProcess(IsTrickPlaySample(kStartTime + kTrickPlaySampleDuration * i,
|
||||||
kTrickPlaySampleDuration)));
|
kTrickPlaySampleDuration)));
|
||||||
}
|
}
|
||||||
EXPECT_CALL(*output(),
|
EXPECT_CALL(*Output(kOutputIndex),
|
||||||
OnProcess(IsSegmentInfo(kStreamIndex, kStartTime, 4 * kDuration,
|
OnProcess(IsSegmentInfo(kStreamIndex, kStartTime, 4 * kDuration,
|
||||||
!kSubSegment, !kEncrypted)));
|
!kSubSegment, !kEncrypted)));
|
||||||
|
|
||||||
// Segment Two
|
// Segment Two
|
||||||
for (int i = 2; i < 4; i++) {
|
for (int i = 2; i < 4; i++) {
|
||||||
EXPECT_CALL(*output(), OnProcess(IsTrickPlaySample(
|
EXPECT_CALL(
|
||||||
kStartTime + kTrickPlaySampleDuration * i,
|
*Output(kOutputIndex),
|
||||||
|
OnProcess(IsTrickPlaySample(kStartTime + kTrickPlaySampleDuration * i,
|
||||||
kTrickPlaySampleDuration)));
|
kTrickPlaySampleDuration)));
|
||||||
}
|
}
|
||||||
EXPECT_CALL(*output(), OnProcess(IsSegmentInfo(
|
EXPECT_CALL(
|
||||||
kStreamIndex, kStartTime + 4 * kDuration,
|
*Output(kOutputIndex),
|
||||||
|
OnProcess(IsSegmentInfo(kStreamIndex, kStartTime + 4 * kDuration,
|
||||||
4 * kDuration, !kSubSegment, !kEncrypted)));
|
4 * kDuration, !kSubSegment, !kEncrypted)));
|
||||||
|
|
||||||
EXPECT_CALL(*output(), OnFlush(0u));
|
EXPECT_CALL(*Output(kOutputIndex), OnFlush(0u));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::shared_ptr<MediaSample>> segment_one_samples =
|
std::vector<std::shared_ptr<MediaSample>> segment_one_samples =
|
||||||
|
@ -256,27 +257,33 @@ TEST_F(TrickPlayHandlerTest, TrickTrackWithSamplesAndSegments) {
|
||||||
CreateSamples(4 /* sample count */, kStartTime + 4 * kDuration, kDuration,
|
CreateSamples(4 /* sample count */, kStartTime + 4 * kDuration, kDuration,
|
||||||
kKeyFrameRate);
|
kKeyFrameRate);
|
||||||
|
|
||||||
ASSERT_OK(input()->Dispatch(StreamData::FromStreamInfo(
|
ASSERT_OK(Input(kInputIndex)
|
||||||
|
->Dispatch(StreamData::FromStreamInfo(
|
||||||
kStreamIndex, GetVideoStreamInfo(kTimescale))));
|
kStreamIndex, GetVideoStreamInfo(kTimescale))));
|
||||||
|
|
||||||
// Segment One
|
// Segment One
|
||||||
for (const auto& sample : segment_one_samples) {
|
for (const auto& sample : segment_one_samples) {
|
||||||
ASSERT_OK(
|
ASSERT_OK(
|
||||||
input()->Dispatch(StreamData::FromMediaSample(kStreamIndex, sample)));
|
Input(kInputIndex)
|
||||||
|
->Dispatch(StreamData::FromMediaSample(kStreamIndex, sample)));
|
||||||
}
|
}
|
||||||
ASSERT_OK(input()->Dispatch(StreamData::FromSegmentInfo(
|
ASSERT_OK(Input(kInputIndex)
|
||||||
kStreamIndex, GetSegmentInfo(kStartTime, kDuration * 4, !kEncrypted))));
|
->Dispatch(StreamData::FromSegmentInfo(
|
||||||
|
kStreamIndex,
|
||||||
|
GetSegmentInfo(kStartTime, kDuration * 4, !kEncrypted))));
|
||||||
|
|
||||||
// Segment Two
|
// Segment Two
|
||||||
for (const auto& sample : segment_two_samples) {
|
for (const auto& sample : segment_two_samples) {
|
||||||
ASSERT_OK(
|
ASSERT_OK(
|
||||||
input()->Dispatch(StreamData::FromMediaSample(kStreamIndex, sample)));
|
Input(kInputIndex)
|
||||||
|
->Dispatch(StreamData::FromMediaSample(kStreamIndex, sample)));
|
||||||
}
|
}
|
||||||
ASSERT_OK(input()->Dispatch(StreamData::FromSegmentInfo(
|
ASSERT_OK(Input(kInputIndex)
|
||||||
kStreamIndex,
|
->Dispatch(StreamData::FromSegmentInfo(
|
||||||
GetSegmentInfo(kStartTime + 4 * kDuration, 4 * kDuration, !kEncrypted))));
|
kStreamIndex, GetSegmentInfo(kStartTime + 4 * kDuration,
|
||||||
|
4 * kDuration, !kEncrypted))));
|
||||||
|
|
||||||
ASSERT_OK(input()->FlushAllDownstreams());
|
ASSERT_OK(Input(kInputIndex)->FlushAllDownstreams());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace media
|
} // namespace media
|
||||||
|
|
Loading…
Reference in New Issue