blob: b0a0ae26b0430e51eeb6464de7d44da0c20eada4 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/mirroring/service/rtp_stream.h"
#include "base/bind_helpers.h"
#include "base/run_loop.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_task_environment.h"
#include "base/test/simple_test_tick_clock.h"
#include "media/base/video_frame.h"
#include "media/cast/cast_config.h"
#include "media/cast/cast_environment.h"
#include "media/cast/sender/audio_sender.h"
#include "media/cast/sender/video_sender.h"
#include "media/cast/test/mock_cast_transport.h"
#include "media/cast/test/utility/audio_utility.h"
#include "media/cast/test/utility/default_config.h"
#include "media/cast/test/utility/video_utility.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using ::testing::InvokeWithoutArgs;
using ::testing::_;
using media::cast::TestAudioBusFactory;
namespace mirroring {
namespace {
class DummyClient final : public RtpStreamClient {
public:
DummyClient() : weak_factory_(this) {}
~DummyClient() override {}
// RtpStreamClient implementation.
void OnError(const std::string& message) override {}
void RequestRefreshFrame() override {}
void CreateVideoEncodeAccelerator(
const media::cast::ReceiveVideoEncodeAcceleratorCallback& callback)
override {}
void CreateVideoEncodeMemory(
size_t size,
const media::cast::ReceiveVideoEncodeMemoryCallback& callback) override {}
base::WeakPtr<RtpStreamClient> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
private:
base::WeakPtrFactory<DummyClient> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(DummyClient);
};
} // namespace
class RtpStreamTest : public ::testing::Test {
public:
RtpStreamTest()
: cast_environment_(new media::cast::CastEnvironment(
&testing_clock_,
scoped_task_environment_.GetMainThreadTaskRunner(),
scoped_task_environment_.GetMainThreadTaskRunner(),
scoped_task_environment_.GetMainThreadTaskRunner())) {
testing_clock_.Advance(base::TimeTicks::Now() - base::TimeTicks());
}
~RtpStreamTest() override { scoped_task_environment_.RunUntilIdle(); }
protected:
base::test::ScopedTaskEnvironment scoped_task_environment_;
base::SimpleTestTickClock testing_clock_;
const scoped_refptr<media::cast::CastEnvironment> cast_environment_;
DummyClient client_;
media::cast::MockCastTransport transport_;
private:
DISALLOW_COPY_AND_ASSIGN(RtpStreamTest);
};
// Test the video streaming pipeline.
TEST_F(RtpStreamTest, VideoStreaming) {
// Create one video frame.
gfx::Size size(64, 32);
scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame(
media::PIXEL_FORMAT_I420, size, gfx::Rect(size), size, base::TimeDelta());
media::cast::PopulateVideoFrame(video_frame.get(), 1);
video_frame->metadata()->SetTimeTicks(
media::VideoFrameMetadata::REFERENCE_TIME, testing_clock_.NowTicks());
auto video_sender = std::make_unique<media::cast::VideoSender>(
cast_environment_, media::cast::GetDefaultVideoSenderConfig(),
base::DoNothing(), base::DoNothing(), base::DoNothing(), &transport_,
base::DoNothing());
VideoRtpStream video_stream(std::move(video_sender), client_.GetWeakPtr());
{
base::RunLoop run_loop;
// Expect the video frame is sent to video sender for encoding, and the
// encoded frame is sent to the transport.
EXPECT_CALL(transport_, InsertFrame(_, _))
.WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
video_stream.InsertVideoFrame(std::move(video_frame));
run_loop.Run();
}
scoped_task_environment_.RunUntilIdle();
}
// Test the audio streaming pipeline.
TEST_F(RtpStreamTest, AudioStreaming) {
// Create audio data.
const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
media::cast::FrameSenderConfig audio_config =
media::cast::GetDefaultAudioSenderConfig();
std::unique_ptr<media::AudioBus> audio_bus =
TestAudioBusFactory(audio_config.channels, audio_config.rtp_timebase,
TestAudioBusFactory::kMiddleANoteFreq, 0.5f)
.NextAudioBus(kDuration);
auto audio_sender = std::make_unique<media::cast::AudioSender>(
cast_environment_, audio_config, base::DoNothing(), &transport_);
AudioRtpStream audio_stream(std::move(audio_sender), client_.GetWeakPtr());
{
base::RunLoop run_loop;
// Expect the audio data is sent to audio sender for encoding, and the
// encoded frame is sent to the transport.
EXPECT_CALL(transport_, InsertFrame(_, _))
.WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
audio_stream.InsertAudio(std::move(audio_bus), testing_clock_.NowTicks());
run_loop.Run();
}
scoped_task_environment_.RunUntilIdle();
}
} // namespace mirroring