Align Trick Play Tests With Other Media Tests

We have adopted some new standards for how we are writing the media
unit tests. This change goes through the trick play tests and
updates them to be more inline with how we are doing new media
tests.

This include using "_" for parameters that are not the focus of the
tests (used in the EXPECT calls).

This includes wrapping Dispatch calls so that the test bodies can
be more readable.

Change-Id: Iab4b1ce67666b6c8a4a821db1a8f4369cd366dc3
This commit is contained in:
Aaron Vaage 2018-06-14 14:01:55 -07:00
parent bf29257e48
commit 8d800446f3
1 changed files with 167 additions and 153 deletions

View File

@ -14,6 +14,8 @@
#include "packager/media/base/video_stream_info.h" #include "packager/media/base/video_stream_info.h"
#include "packager/status_test_util.h" #include "packager/status_test_util.h"
using ::testing::_;
namespace shaka { namespace shaka {
namespace media { namespace media {
namespace { namespace {
@ -27,58 +29,37 @@ const size_t kStreamIndex = 0;
// to create the audio and video info. // to create the audio and video info.
const uint32_t kTimescale = 1000u; const uint32_t kTimescale = 1000u;
const bool kSubSegment = true; const bool kKeyFrame = true;
const bool kEncrypted = true;
} // namespace } // namespace
MATCHER_P2(IsTrickPlayVideoStream, trick_play_factor, playback_rate, "") {
if (arg->stream_data_type != StreamDataType::kStreamInfo ||
arg->stream_info->stream_type() != kStreamVideo) {
return false;
}
const VideoStreamInfo* video_info =
static_cast<const VideoStreamInfo*>(arg->stream_info.get());
return video_info->trick_play_factor() == trick_play_factor &&
video_info->playback_rate() == playback_rate;
}
MATCHER_P2(IsTrickPlaySample, timestamp, duration, "") {
return arg->stream_index == kStreamIndex &&
arg->stream_data_type == StreamDataType::kMediaSample &&
arg->media_sample->dts() == timestamp &&
arg->media_sample->duration() == duration &&
arg->media_sample->is_key_frame();
}
class TrickPlayHandlerTest : public MediaHandlerTestBase { class TrickPlayHandlerTest : public MediaHandlerTestBase {
protected: protected:
void SetUpAndInitializeGraph(uint32_t factor) { void SetUpAndInitializeGraph(uint32_t factor) {
ASSERT_OK(MediaHandlerTestBase::SetUpAndInitializeGraph( ASSERT_OK(MediaHandlerTestBase::SetUpAndInitializeGraph(
std::make_shared<TrickPlayHandler>(factor), std::make_shared<TrickPlayHandler>(factor), kInputCount, kOutputCount));
kInputCount,
kOutputCount));
} }
// Create a series of samples where each sample has the same duration and ever Status DispatchVideoInfo() {
// sample that is an even multiple of |key_frame_frequency| will be a key auto info = GetVideoStreamInfo(kTimescale);
// frame. auto data = StreamData::FromStreamInfo(kStreamIndex, std::move(info));
std::vector<std::shared_ptr<MediaSample>> CreateSamples( return Input(kInputIndex)->Dispatch(std::move(data));
size_t count,
uint64_t start_time,
uint64_t frame_duration,
size_t key_frame_frequency) {
std::vector<std::shared_ptr<MediaSample>> samples;
uint64_t time = start_time;
for (size_t sample_index = 0; sample_index < count; sample_index++) {
const bool is_key_frame = (sample_index % key_frame_frequency) == 0;
samples.push_back(GetMediaSample(time, frame_duration, is_key_frame));
time += frame_duration;
} }
return samples; Status DispatchSample(int64_t time, int64_t duration, bool keyframe) {
auto sample = GetMediaSample(time, duration, keyframe);
auto data = StreamData::FromMediaSample(kStreamIndex, std::move(sample));
return Input(kInputIndex)->Dispatch(std::move(data));
} }
Status DispatchSegment(int64_t start_time, int64_t duration) {
const bool kSubSegment = true;
auto info = GetSegmentInfo(start_time, duration, !kSubSegment);
auto data = StreamData::FromSegmentInfo(kStreamIndex, std::move(info));
return Input(kInputIndex)->Dispatch(std::move(data));
}
Status Flush() { return Input(kInputIndex)->FlushAllDownstreams(); }
}; };
// 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.
@ -86,9 +67,9 @@ TEST_F(TrickPlayHandlerTest, RejectsAudio) {
const uint32_t kTrickPlayFactor = 1u; const uint32_t kTrickPlayFactor = 1u;
SetUpAndInitializeGraph(kTrickPlayFactor); SetUpAndInitializeGraph(kTrickPlayFactor);
Status status = Input(kInputIndex) auto info = GetAudioStreamInfo(kTimescale);
->Dispatch(StreamData::FromStreamInfo( auto data = StreamData::FromStreamInfo(kStreamIndex, std::move(info));
kStreamIndex, GetAudioStreamInfo(kTimescale))); Status status = Input(kInputIndex)->Dispatch(std::move(data));
EXPECT_EQ(error::TRICK_PLAY_ERROR, status.error_code()); EXPECT_EQ(error::TRICK_PLAY_ERROR, status.error_code());
} }
@ -106,14 +87,12 @@ TEST_F(TrickPlayHandlerTest, TrickTrackNoSamples) {
{ {
testing::InSequence s; testing::InSequence s;
EXPECT_CALL(*Output(kOutputIndex), EXPECT_CALL(*Output(kOutputIndex),
OnProcess(IsTrickPlayVideoStream(kTrickPlayFactor, kPlayRate))); OnProcess(IsVideoStream(_, kTrickPlayFactor, kPlayRate)));
EXPECT_CALL(*Output(kOutputIndex), OnFlush(kStreamIndex)); EXPECT_CALL(*Output(kOutputIndex), OnFlush(_));
} }
ASSERT_OK(Input(kInputIndex) ASSERT_OK(DispatchVideoInfo());
->Dispatch(StreamData::FromStreamInfo( ASSERT_OK(Flush());
kStreamIndex, GetVideoStreamInfo(kTimescale))));
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
@ -121,12 +100,23 @@ TEST_F(TrickPlayHandlerTest, TrickTrackNoSamples) {
// through. // through.
TEST_F(TrickPlayHandlerTest, TrickTrackWithSamplesOnlyGetsKeyFrames) { TEST_F(TrickPlayHandlerTest, TrickTrackWithSamplesOnlyGetsKeyFrames) {
const uint32_t kTrickPlayFactor = 1u; const uint32_t kTrickPlayFactor = 1u;
const int64_t kStartTime = 0;
const int64_t kDuration = 100;
const int64_t kKeyFrameRate = 3;
const int64_t kPlayRate = kKeyFrameRate * kTrickPlayFactor; const int64_t kFrameDuration = 100;
const int64_t kTrickPlaySampleDuration = kDuration * kPlayRate; const int64_t kFrame0 = 0;
const int64_t kFrame1 = 100;
const int64_t kFrame2 = 200;
const int64_t kFrame3 = 300;
const int64_t kFrame4 = 400;
const int64_t kFrame5 = 500;
const int64_t kFrame6 = 600;
const int64_t kFrame7 = 700;
const int64_t kFrame8 = 800;
// Key frame every three frames.
// Use every key frame in the trick play stream.
// A single trick play frame has 3 times the duration of a normal frame.
const int64_t kPlayRate = 3;
const int64_t kTrickPlayDuration = kFrameDuration * 3;
SetUpAndInitializeGraph(kTrickPlayFactor); SetUpAndInitializeGraph(kTrickPlayFactor);
@ -135,30 +125,37 @@ TEST_F(TrickPlayHandlerTest, TrickTrackWithSamplesOnlyGetsKeyFrames) {
{ {
testing::InSequence s; testing::InSequence s;
EXPECT_CALL(*Output(kOutputIndex), EXPECT_CALL(*Output(kOutputIndex),
OnProcess(IsTrickPlayVideoStream(kTrickPlayFactor, kPlayRate))); OnProcess(IsVideoStream(_, kTrickPlayFactor, kPlayRate)));
for (int i = 0; i < 3; i++) {
EXPECT_CALL( EXPECT_CALL(
*Output(kOutputIndex), *Output(kOutputIndex),
OnProcess(IsTrickPlaySample(kStartTime + i * kTrickPlaySampleDuration, OnProcess(IsMediaSample(_, kFrame0, kTrickPlayDuration, _, kKeyFrame)));
kTrickPlaySampleDuration))); EXPECT_CALL(
} *Output(kOutputIndex),
EXPECT_CALL(*Output(kOutputIndex), OnFlush(kStreamIndex)); OnProcess(IsMediaSample(_, kFrame3, kTrickPlayDuration, _, kKeyFrame)));
EXPECT_CALL(
*Output(kOutputIndex),
OnProcess(IsMediaSample(_, kFrame6, kTrickPlayDuration, _, kKeyFrame)));
EXPECT_CALL(*Output(kOutputIndex), OnFlush(_));
} }
std::vector<std::shared_ptr<MediaSample>> samples = ASSERT_OK(DispatchVideoInfo());
CreateSamples(9 /* sample count */, kStartTime, kDuration, kKeyFrameRate);
ASSERT_OK(Input(kInputIndex) // GOP 1
->Dispatch(StreamData::FromStreamInfo( ASSERT_OK(DispatchSample(kFrame0, kFrameDuration, kKeyFrame));
kStreamIndex, GetVideoStreamInfo(kTimescale)))); ASSERT_OK(DispatchSample(kFrame1, kFrameDuration, !kKeyFrame));
ASSERT_OK(DispatchSample(kFrame2, kFrameDuration, !kKeyFrame));
for (const auto& sample : samples) { // GOP 2
ASSERT_OK( ASSERT_OK(DispatchSample(kFrame3, kFrameDuration, kKeyFrame));
Input(kInputIndex) ASSERT_OK(DispatchSample(kFrame4, kFrameDuration, !kKeyFrame));
->Dispatch(StreamData::FromMediaSample(kStreamIndex, sample))); ASSERT_OK(DispatchSample(kFrame5, kFrameDuration, !kKeyFrame));
}
ASSERT_OK(Input(kInputIndex)->FlushAllDownstreams()); // GOP 3
ASSERT_OK(DispatchSample(kFrame6, kFrameDuration, kKeyFrame));
ASSERT_OK(DispatchSample(kFrame7, kFrameDuration, !kKeyFrame));
ASSERT_OK(DispatchSample(kFrame8, kFrameDuration, !kKeyFrame));
ASSERT_OK(Flush());
} }
// 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
@ -166,12 +163,22 @@ TEST_F(TrickPlayHandlerTest, TrickTrackWithSamplesOnlyGetsKeyFrames) {
// through. // through.
TEST_F(TrickPlayHandlerTest, TrickTrackWithSamples) { TEST_F(TrickPlayHandlerTest, TrickTrackWithSamples) {
const uint32_t kTrickPlayFactor = 2u; const uint32_t kTrickPlayFactor = 2u;
const int64_t kStartTime = 0;
const int64_t kDuration = 100;
const int64_t kKeyFrameRate = 2;
const int64_t kPlayRate = kKeyFrameRate * kTrickPlayFactor; const int64_t kFrameDuration = 100;
const int64_t kTrickPlaySampleDuration = kDuration * kPlayRate; const int64_t kFrame0 = 0;
const int64_t kFrame1 = 100;
const int64_t kFrame2 = 200;
const int64_t kFrame3 = 300;
const int64_t kFrame4 = 400;
const int64_t kFrame5 = 500;
const int64_t kFrame6 = 600;
const int64_t kFrame7 = 700;
// Key frame every two frames.
// Use every second key frame in the trick play stream.
// A single trick play frame has 4 times the duration of a normal frame.
const int64_t kPlayRate = 4;
const int64_t kTrickPlayDuration = kFrameDuration * 4;
SetUpAndInitializeGraph(kTrickPlayFactor); SetUpAndInitializeGraph(kTrickPlayFactor);
@ -180,40 +187,59 @@ TEST_F(TrickPlayHandlerTest, TrickTrackWithSamples) {
{ {
testing::InSequence s; testing::InSequence s;
EXPECT_CALL(*Output(kOutputIndex), EXPECT_CALL(*Output(kOutputIndex),
OnProcess(IsTrickPlayVideoStream(kTrickPlayFactor, kPlayRate))); OnProcess(IsVideoStream(_, kTrickPlayFactor, kPlayRate)));
for (int i = 0; i < 2; i++) {
EXPECT_CALL( EXPECT_CALL(
*Output(kOutputIndex), *Output(kOutputIndex),
OnProcess(IsTrickPlaySample(kStartTime + i * kTrickPlaySampleDuration, OnProcess(IsMediaSample(_, kFrame0, kTrickPlayDuration, _, kKeyFrame)));
kTrickPlaySampleDuration))); EXPECT_CALL(
} *Output(kOutputIndex),
EXPECT_CALL(*Output(kOutputIndex), OnFlush(0u)); OnProcess(IsMediaSample(_, kFrame4, kTrickPlayDuration, _, kKeyFrame)));
EXPECT_CALL(*Output(kOutputIndex), OnFlush(_));
} }
std::vector<std::shared_ptr<MediaSample>> samples = ASSERT_OK(DispatchVideoInfo());
CreateSamples(8 /* sample count */, kStartTime, kDuration, kKeyFrameRate);
ASSERT_OK(Input(kInputIndex) // GOP 1
->Dispatch(StreamData::FromStreamInfo( ASSERT_OK(DispatchSample(kFrame0, kFrameDuration, kKeyFrame));
kStreamIndex, GetVideoStreamInfo(kTimescale)))); ASSERT_OK(DispatchSample(kFrame1, kFrameDuration, !kKeyFrame));
for (const auto& sample : samples) { // GOP 2
ASSERT_OK( ASSERT_OK(DispatchSample(kFrame2, kFrameDuration, kKeyFrame));
Input(kInputIndex) ASSERT_OK(DispatchSample(kFrame3, kFrameDuration, !kKeyFrame));
->Dispatch(StreamData::FromMediaSample(kStreamIndex, sample)));
}
ASSERT_OK(Input(kInputIndex)->FlushAllDownstreams()); // GOP 3
ASSERT_OK(DispatchSample(kFrame4, kFrameDuration, kKeyFrame));
ASSERT_OK(DispatchSample(kFrame5, kFrameDuration, !kKeyFrame));
// GOP 4
ASSERT_OK(DispatchSample(kFrame6, kFrameDuration, kKeyFrame));
ASSERT_OK(DispatchSample(kFrame7, kFrameDuration, !kKeyFrame));
ASSERT_OK(Flush());
} }
TEST_F(TrickPlayHandlerTest, TrickTrackWithSamplesAndSegments) { TEST_F(TrickPlayHandlerTest, TrickTrackWithSamplesAndSegments) {
const uint32_t kTrickPlayFactor = 1u; const uint32_t kTrickPlayFactor = 1u;
const int64_t kStartTime = 0;
const int64_t kDuration = 100;
const int64_t kKeyFrameRate = 2;
const int64_t kPlayRate = kKeyFrameRate * kTrickPlayFactor; const int64_t kFrameDuration = 100;
const int64_t kTrickPlaySampleDuration = kDuration * kPlayRate; const int64_t kFrame0 = 0;
const int64_t kFrame1 = 100;
const int64_t kFrame2 = 200;
const int64_t kFrame3 = 300;
const int64_t kFrame4 = 400;
const int64_t kFrame5 = 500;
const int64_t kFrame6 = 600;
const int64_t kFrame7 = 700;
const int64_t kSegmentDuration = 400;
const int64_t kSegment0 = 0;
const int64_t kSegment1 = 400;
// Key frame every two frames.
// Use every key frame in the trick play stream.
// This means that each trick play frame covers two normal frames.
const int64_t kPlayRate = 2;
const int64_t kTrickPlayDuration = kFrameDuration * 2;
SetUpAndInitializeGraph(kTrickPlayFactor); SetUpAndInitializeGraph(kTrickPlayFactor);
@ -222,68 +248,56 @@ TEST_F(TrickPlayHandlerTest, TrickTrackWithSamplesAndSegments) {
{ {
testing::InSequence s; testing::InSequence s;
EXPECT_CALL(*Output(kOutputIndex), EXPECT_CALL(*Output(kOutputIndex),
OnProcess(IsTrickPlayVideoStream(kTrickPlayFactor, kPlayRate))); OnProcess(IsVideoStream(_, kTrickPlayFactor, kPlayRate)));
// Segment One // Segment One
for (int i = 0; i < 2; i++) {
EXPECT_CALL( EXPECT_CALL(
*Output(kOutputIndex), *Output(kOutputIndex),
OnProcess(IsTrickPlaySample(kStartTime + kTrickPlaySampleDuration * i, OnProcess(IsMediaSample(_, kFrame0, kTrickPlayDuration, _, kKeyFrame)));
kTrickPlaySampleDuration))); EXPECT_CALL(
} *Output(kOutputIndex),
OnProcess(IsMediaSample(_, kFrame2, kTrickPlayDuration, _, kKeyFrame)));
EXPECT_CALL(*Output(kOutputIndex), EXPECT_CALL(*Output(kOutputIndex),
OnProcess(IsSegmentInfo(kStreamIndex, kStartTime, 4 * kDuration, OnProcess(IsSegmentInfo(_, kSegment0, kSegmentDuration, _, _)));
!kSubSegment, !kEncrypted)));
// Segment Two // Segment Two
for (int i = 2; i < 4; i++) {
EXPECT_CALL( EXPECT_CALL(
*Output(kOutputIndex), *Output(kOutputIndex),
OnProcess(IsTrickPlaySample(kStartTime + kTrickPlaySampleDuration * i, OnProcess(IsMediaSample(_, kFrame4, kTrickPlayDuration, _, kKeyFrame)));
kTrickPlaySampleDuration)));
}
EXPECT_CALL( EXPECT_CALL(
*Output(kOutputIndex), *Output(kOutputIndex),
OnProcess(IsSegmentInfo(kStreamIndex, kStartTime + 4 * kDuration, OnProcess(IsMediaSample(_, kFrame6, kTrickPlayDuration, _, kKeyFrame)));
4 * kDuration, !kSubSegment, !kEncrypted))); EXPECT_CALL(*Output(kOutputIndex),
OnProcess(IsSegmentInfo(_, kSegment1, kSegmentDuration, _, _)));
EXPECT_CALL(*Output(kOutputIndex), OnFlush(0u)); EXPECT_CALL(*Output(kOutputIndex), OnFlush(_));
} }
std::vector<std::shared_ptr<MediaSample>> segment_one_samples = ASSERT_OK(DispatchVideoInfo());
CreateSamples(4 /* sample count */, kStartTime, kDuration, kKeyFrameRate);
std::vector<std::shared_ptr<MediaSample>> segment_two_samples = // GOP 1
CreateSamples(4 /* sample count */, kStartTime + 4 * kDuration, kDuration, ASSERT_OK(DispatchSample(kFrame0, kFrameDuration, kKeyFrame));
kKeyFrameRate); ASSERT_OK(DispatchSample(kFrame1, kFrameDuration, !kKeyFrame));
ASSERT_OK(Input(kInputIndex) // GOP 2
->Dispatch(StreamData::FromStreamInfo( ASSERT_OK(DispatchSample(kFrame2, kFrameDuration, kKeyFrame));
kStreamIndex, GetVideoStreamInfo(kTimescale)))); ASSERT_OK(DispatchSample(kFrame3, kFrameDuration, !kKeyFrame));
// Segment One // Segment One
for (const auto& sample : segment_one_samples) { ASSERT_OK(DispatchSegment(kSegment0, kSegmentDuration));
ASSERT_OK(
Input(kInputIndex) // GOP 3
->Dispatch(StreamData::FromMediaSample(kStreamIndex, sample))); ASSERT_OK(DispatchSample(kFrame4, kFrameDuration, kKeyFrame));
} ASSERT_OK(DispatchSample(kFrame5, kFrameDuration, !kKeyFrame));
ASSERT_OK(Input(kInputIndex)
->Dispatch(StreamData::FromSegmentInfo( // GOP 4
kStreamIndex, ASSERT_OK(DispatchSample(kFrame6, kFrameDuration, kKeyFrame));
GetSegmentInfo(kStartTime, kDuration * 4, !kEncrypted)))); ASSERT_OK(DispatchSample(kFrame7, kFrameDuration, !kKeyFrame));
// Segment Two // Segment Two
for (const auto& sample : segment_two_samples) { ASSERT_OK(DispatchSegment(kSegment1, kSegmentDuration));
ASSERT_OK(
Input(kInputIndex)
->Dispatch(StreamData::FromMediaSample(kStreamIndex, sample)));
}
ASSERT_OK(Input(kInputIndex)
->Dispatch(StreamData::FromSegmentInfo(
kStreamIndex, GetSegmentInfo(kStartTime + 4 * kDuration,
4 * kDuration, !kEncrypted))));
ASSERT_OK(Input(kInputIndex)->FlushAllDownstreams()); ASSERT_OK(Flush());
} }
} // namespace media } // namespace media