summaryrefslogtreecommitdiff
path: root/chromium/media/remoting/stream_provider_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/media/remoting/stream_provider_unittest.cc')
-rw-r--r--chromium/media/remoting/stream_provider_unittest.cc316
1 files changed, 316 insertions, 0 deletions
diff --git a/chromium/media/remoting/stream_provider_unittest.cc b/chromium/media/remoting/stream_provider_unittest.cc
new file mode 100644
index 00000000000..7ad43222db0
--- /dev/null
+++ b/chromium/media/remoting/stream_provider_unittest.cc
@@ -0,0 +1,316 @@
+// Copyright 2020 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 "media/remoting/stream_provider.h"
+
+#include "base/test/task_environment.h"
+#include "media/base/audio_decoder_config.h"
+#include "media/base/demuxer_stream.h"
+#include "media/base/media_util.h"
+#include "media/base/test_helpers.h"
+#include "media/base/video_decoder_config.h"
+#include "media/remoting/mock_receiver_controller.h"
+#include "media/remoting/proto_enum_utils.h"
+#include "media/remoting/proto_utils.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::NiceMock;
+
+namespace {
+constexpr int kBufferSize = 10;
+} // namespace
+
+namespace media {
+namespace remoting {
+
+class StreamProviderTest : public testing::Test {
+ public:
+ StreamProviderTest()
+ : audio_config_(TestAudioConfig::Normal()),
+ video_config_(TestVideoConfig::Normal()),
+ audio_buffer_(new DecoderBuffer(kBufferSize)),
+ video_buffer_(DecoderBuffer::CreateEOSBuffer()) {}
+
+ void SetUp() override {
+ mock_controller_ = MockReceiverController::GetInstance();
+ mock_controller_->Initialize(
+ mock_controller_->mock_remotee()->BindNewPipeAndPassRemote());
+ mock_remotee_ = mock_controller_->mock_remotee();
+ stream_provider_ = std::make_unique<StreamProvider>(
+ mock_controller_, base::ThreadTaskRunnerHandle::Get());
+
+ rpc_broker_ = mock_controller_->rpc_broker();
+ sender_audio_demuxer_stream_handle_ = rpc_broker_->GetUniqueHandle();
+ sender_video_demuxer_stream_handle_ = rpc_broker_->GetUniqueHandle();
+ rpc_broker_->RegisterMessageReceiverCallback(
+ sender_audio_demuxer_stream_handle_,
+ base::BindRepeating(&StreamProviderTest::OnDemuxerStreamReceivedRpc,
+ base::Unretained(this),
+ DemuxerStream::Type::AUDIO));
+ rpc_broker_->RegisterMessageReceiverCallback(
+ sender_video_demuxer_stream_handle_,
+ base::BindRepeating(&StreamProviderTest::OnDemuxerStreamReceivedRpc,
+ base::Unretained(this),
+ DemuxerStream::Type::VIDEO));
+ }
+
+ void TearDown() override {
+ stream_provider_.reset();
+ task_environment_.RunUntilIdle();
+ }
+
+ void OnDemuxerStreamReceivedRpc(DemuxerStream::Type type,
+ std::unique_ptr<pb::RpcMessage> message) {
+ DCHECK(message);
+ switch (message->proc()) {
+ case pb::RpcMessage::RPC_DS_INITIALIZE:
+ if (type == DemuxerStream::Type::AUDIO) {
+ receiver_audio_demuxer_stream_handle_ = message->integer_value();
+ } else if (type == DemuxerStream::Type::VIDEO) {
+ receiver_video_demuxer_stream_handle_ = message->integer_value();
+ } else {
+ NOTREACHED();
+ }
+
+ RpcInitializeCallback(type);
+ break;
+
+ case pb::RpcMessage::RPC_DS_READUNTIL:
+ ReadUntil(type);
+ break;
+
+ default:
+ DVLOG(1) << __func__ << "Unknown supported message.";
+ }
+ }
+
+ void RpcInitializeCallback(DemuxerStream::Type type) {
+ // Issues RPC_DS_INITIALIZE_CALLBACK RPC message.
+ auto rpc = std::make_unique<pb::RpcMessage>();
+ rpc->set_handle(type == DemuxerStream::Type::AUDIO
+ ? receiver_audio_demuxer_stream_handle_
+ : receiver_video_demuxer_stream_handle_);
+ rpc->set_proc(pb::RpcMessage::RPC_DS_INITIALIZE_CALLBACK);
+ auto* init_cb_message = rpc->mutable_demuxerstream_initializecb_rpc();
+ init_cb_message->set_type(type);
+
+ switch (type) {
+ case DemuxerStream::Type::AUDIO: {
+ pb::AudioDecoderConfig* audio_message =
+ init_cb_message->mutable_audio_decoder_config();
+ ConvertAudioDecoderConfigToProto(audio_config_, audio_message);
+ break;
+ }
+
+ case DemuxerStream::Type::VIDEO: {
+ pb::VideoDecoderConfig* video_message =
+ init_cb_message->mutable_video_decoder_config();
+ ConvertVideoDecoderConfigToProto(video_config_, video_message);
+ break;
+ }
+
+ default:
+ NOTREACHED();
+ }
+
+ rpc_broker_->SendMessageToRemote(std::move(rpc));
+ }
+
+ void ReadUntil(DemuxerStream::Type type) {
+ switch (type) {
+ case DemuxerStream::Type::AUDIO:
+ SendAudioFrame();
+ break;
+ case DemuxerStream::Type::VIDEO:
+ SendVideoFrame();
+ break;
+ default:
+ NOTREACHED();
+ }
+ }
+
+ void SendRpcAcquireDemuxer() {
+ auto rpc = std::make_unique<pb::RpcMessage>();
+ rpc->set_handle(RpcBroker::kAcquireDemuxerHandle);
+ rpc->set_proc(pb::RpcMessage::RPC_ACQUIRE_DEMUXER);
+ pb::AcquireDemuxer* message = rpc->mutable_acquire_demuxer_rpc();
+ message->set_audio_demuxer_handle(sender_audio_demuxer_stream_handle_);
+ message->set_video_demuxer_handle(sender_video_demuxer_stream_handle_);
+ rpc_broker_->SendMessageToRemote(std::move(rpc));
+ }
+
+ void OnStreamProviderInitialized(PipelineStatus status) {
+ EXPECT_EQ(PipelineStatus::PIPELINE_OK, status);
+ stream_provider_initialized_ = true;
+ audio_stream_ =
+ stream_provider_->GetFirstStream(DemuxerStream::Type::AUDIO);
+ video_stream_ =
+ stream_provider_->GetFirstStream(DemuxerStream::Type::VIDEO);
+
+ EXPECT_TRUE(audio_stream_);
+ EXPECT_TRUE(video_stream_);
+ }
+
+ void InitializeDemuxer() {
+ DCHECK(stream_provider_);
+ stream_provider_->Initialize(
+ nullptr,
+ base::BindOnce(&StreamProviderTest::OnStreamProviderInitialized,
+ base::Unretained(this)));
+ }
+
+ void SendAudioFrame() {
+ mock_remotee_->SendAudioFrame(0, audio_buffer_);
+ SendRpcReadUntilCallback(DemuxerStream::Type::AUDIO);
+ }
+
+ void SendVideoFrame() {
+ mock_remotee_->SendVideoFrame(0, video_buffer_);
+ SendRpcReadUntilCallback(DemuxerStream::Type::VIDEO);
+ }
+
+ void SendRpcReadUntilCallback(DemuxerStream::Type type) {
+ // Issues RPC_DS_READUNTIL_CALLBACK RPC message.
+ auto rpc = std::make_unique<pb::RpcMessage>();
+ rpc->set_handle(type == DemuxerStream::Type::AUDIO
+ ? receiver_audio_demuxer_stream_handle_
+ : receiver_video_demuxer_stream_handle_);
+ rpc->set_proc(pb::RpcMessage::RPC_DS_READUNTIL_CALLBACK);
+ auto* message = rpc->mutable_demuxerstream_readuntilcb_rpc();
+ message->set_count(0);
+ message->set_status(
+ ToProtoDemuxerStreamStatus(DemuxerStream::Status::kOk).value());
+ rpc_broker_->SendMessageToRemote(std::move(rpc));
+ }
+
+ void FlushUntil(uint32_t flush_audio_count, uint32_t flush_video_count) {
+ mock_remotee_->OnFlushUntil(flush_audio_count, flush_video_count);
+ }
+
+ uint32_t GetAudioCurrentFrameCount() {
+ return stream_provider_->audio_stream_->current_frame_count_;
+ }
+
+ uint32_t GetVideoCurrentFrameCount() {
+ return stream_provider_->video_stream_->current_frame_count_;
+ }
+
+ void OnBufferReadFromDemuxerStream(DemuxerStream::Type type,
+ DemuxerStream::Status status,
+ scoped_refptr<DecoderBuffer> buffer) {
+ EXPECT_EQ(status, DemuxerStream::Status::kOk);
+ switch (type) {
+ case DemuxerStream::Type::AUDIO:
+ received_audio_buffer_ = buffer;
+ break;
+ case DemuxerStream::Type::VIDEO:
+ received_video_buffer_ = buffer;
+ break;
+ default:
+ NOTREACHED();
+ }
+ }
+
+ base::test::TaskEnvironment task_environment_;
+
+ AudioDecoderConfig audio_config_;
+ VideoDecoderConfig video_config_;
+
+ DemuxerStream* audio_stream_;
+ DemuxerStream* video_stream_;
+
+ scoped_refptr<DecoderBuffer> audio_buffer_;
+ scoped_refptr<DecoderBuffer> video_buffer_;
+
+ bool stream_provider_initialized_{false};
+ scoped_refptr<DecoderBuffer> received_audio_buffer_;
+ scoped_refptr<DecoderBuffer> received_video_buffer_;
+
+ int sender_audio_demuxer_stream_handle_ = RpcBroker::kInvalidHandle;
+ int sender_video_demuxer_stream_handle_ = RpcBroker::kInvalidHandle;
+ int receiver_audio_demuxer_stream_handle_ = RpcBroker::kInvalidHandle;
+ int receiver_video_demuxer_stream_handle_ = RpcBroker::kInvalidHandle;
+
+ RpcBroker* rpc_broker_;
+ MockReceiverController* mock_controller_;
+ MockRemotee* mock_remotee_;
+ std::unique_ptr<StreamProvider> stream_provider_;
+};
+
+TEST_F(StreamProviderTest, InitializeBeforeRpcAcquireDemuxer) {
+ InitializeDemuxer();
+ EXPECT_FALSE(stream_provider_initialized_);
+
+ SendRpcAcquireDemuxer();
+ task_environment_.RunUntilIdle();
+
+ EXPECT_TRUE(mock_remotee_->audio_stream_.is_bound());
+ EXPECT_TRUE(mock_remotee_->video_stream_.is_bound());
+ EXPECT_TRUE(stream_provider_initialized_);
+
+ // 1 audio stream and 1 video stream
+ EXPECT_EQ(size_t(2), stream_provider_->GetAllStreams().size());
+}
+
+TEST_F(StreamProviderTest, InitializeAfterRpcAcquireDemuxer) {
+ SendRpcAcquireDemuxer();
+ EXPECT_FALSE(stream_provider_initialized_);
+
+ InitializeDemuxer();
+ task_environment_.RunUntilIdle();
+
+ EXPECT_TRUE(mock_remotee_->audio_stream_.is_bound());
+ EXPECT_TRUE(mock_remotee_->video_stream_.is_bound());
+ EXPECT_TRUE(stream_provider_initialized_);
+
+ // 1 audio stream and 1 video stream
+ EXPECT_EQ(size_t(2), stream_provider_->GetAllStreams().size());
+}
+
+TEST_F(StreamProviderTest, ReadBuffer) {
+ InitializeDemuxer();
+ SendRpcAcquireDemuxer();
+ task_environment_.RunUntilIdle();
+ EXPECT_TRUE(mock_remotee_->audio_stream_.is_bound());
+ EXPECT_TRUE(mock_remotee_->video_stream_.is_bound());
+ EXPECT_TRUE(stream_provider_initialized_);
+
+ audio_stream_->Read(
+ base::BindOnce(&StreamProviderTest::OnBufferReadFromDemuxerStream,
+ base::Unretained(this), DemuxerStream::Type::AUDIO));
+ task_environment_.RunUntilIdle();
+ EXPECT_EQ(audio_buffer_->data_size(), received_audio_buffer_->data_size());
+ EXPECT_EQ(audio_buffer_->end_of_stream(),
+ received_audio_buffer_->end_of_stream());
+ EXPECT_EQ(audio_buffer_->is_key_frame(),
+ received_audio_buffer_->is_key_frame());
+
+ video_stream_->Read(
+ base::BindOnce(&StreamProviderTest::OnBufferReadFromDemuxerStream,
+ base::Unretained(this), DemuxerStream::Type::VIDEO));
+ task_environment_.RunUntilIdle();
+ EXPECT_EQ(video_buffer_->end_of_stream(),
+ received_video_buffer_->end_of_stream());
+}
+
+TEST_F(StreamProviderTest, FlushUntil) {
+ InitializeDemuxer();
+ SendRpcAcquireDemuxer();
+ task_environment_.RunUntilIdle();
+ EXPECT_TRUE(mock_remotee_->audio_stream_.is_bound());
+ EXPECT_TRUE(mock_remotee_->video_stream_.is_bound());
+ EXPECT_TRUE(stream_provider_initialized_);
+
+ uint32_t flush_audio_count = 10;
+ uint32_t flush_video_count = 20;
+ FlushUntil(flush_audio_count, flush_video_count);
+ task_environment_.RunUntilIdle();
+
+ EXPECT_EQ(GetAudioCurrentFrameCount(), flush_audio_count);
+ EXPECT_EQ(GetVideoCurrentFrameCount(), flush_video_count);
+}
+
+} // namespace remoting
+} // namespace media