Fix FullScreen crash in Webapp
[platform/framework/web/chromium-efl.git] / media / remoting / stream_provider_unittest.cc
1 // Copyright 2020 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/remoting/stream_provider.h"
6
7 #include "base/memory/raw_ptr.h"
8 #include "base/task/single_thread_task_runner.h"
9 #include "base/test/task_environment.h"
10 #include "media/base/audio_decoder_config.h"
11 #include "media/base/demuxer_stream.h"
12 #include "media/base/media_util.h"
13 #include "media/base/test_helpers.h"
14 #include "media/base/video_decoder_config.h"
15 #include "media/cast/openscreen/remoting_proto_enum_utils.h"
16 #include "media/cast/openscreen/remoting_proto_utils.h"
17 #include "media/remoting/mock_receiver_controller.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 using openscreen::cast::RpcMessenger;
22 using testing::NiceMock;
23
24 namespace {
25 constexpr int kBufferSize = 10;
26 }  // namespace
27
28 namespace media {
29 namespace remoting {
30
31 class StreamProviderTest : public testing::Test {
32  public:
33   StreamProviderTest()
34       : audio_config_(TestAudioConfig::Normal()),
35         video_config_(TestVideoConfig::Normal()),
36         audio_buffer_(new DecoderBuffer(kBufferSize)),
37         video_buffer_(DecoderBuffer::CreateEOSBuffer()) {}
38
39   void SetUp() override {
40     mock_controller_ = MockReceiverController::GetInstance();
41     mock_controller_->Initialize(
42         mock_controller_->mock_remotee()->BindNewPipeAndPassRemote());
43     mock_remotee_ = mock_controller_->mock_remotee();
44     stream_provider_ = std::make_unique<StreamProvider>(
45         mock_controller_, base::SingleThreadTaskRunner::GetCurrentDefault());
46
47     rpc_messenger_ = mock_controller_->rpc_messenger();
48     sender_audio_demuxer_stream_handle_ = rpc_messenger_->GetUniqueHandle();
49     sender_video_demuxer_stream_handle_ = rpc_messenger_->GetUniqueHandle();
50     rpc_messenger_->RegisterMessageReceiverCallback(
51         sender_audio_demuxer_stream_handle_,
52         [this](std::unique_ptr<openscreen::cast::RpcMessage> message) {
53           OnDemuxerStreamReceivedRpc(DemuxerStream::Type::AUDIO,
54                                      std::move(message));
55         });
56     rpc_messenger_->RegisterMessageReceiverCallback(
57         sender_video_demuxer_stream_handle_,
58         [this](std::unique_ptr<openscreen::cast::RpcMessage> message) {
59           OnDemuxerStreamReceivedRpc(DemuxerStream::Type::VIDEO,
60                                      std::move(message));
61         });
62   }
63
64   void TearDown() override {
65     // Drop unowned references before `stream_provider_` destroys them.
66     audio_stream_ = nullptr;
67     video_stream_ = nullptr;
68
69     stream_provider_.reset();
70     task_environment_.RunUntilIdle();
71   }
72
73   void OnDemuxerStreamReceivedRpc(
74       DemuxerStream::Type type,
75       std::unique_ptr<openscreen::cast::RpcMessage> message) {
76     DCHECK(message);
77     switch (message->proc()) {
78       case openscreen::cast::RpcMessage::RPC_DS_INITIALIZE:
79         if (type == DemuxerStream::Type::AUDIO) {
80           receiver_audio_demuxer_stream_handle_ = message->integer_value();
81         } else if (type == DemuxerStream::Type::VIDEO) {
82           receiver_video_demuxer_stream_handle_ = message->integer_value();
83         } else {
84           NOTREACHED();
85         }
86
87         RpcInitializeCallback(type);
88         break;
89
90       case openscreen::cast::RpcMessage::RPC_DS_READUNTIL:
91         ReadUntil(type);
92         break;
93
94       default:
95         DVLOG(1) << __func__ << "Unknown supported message.";
96     }
97   }
98
99   void RpcInitializeCallback(DemuxerStream::Type type) {
100     // Issues RPC_DS_INITIALIZE_CALLBACK RPC message.
101     auto rpc = std::make_unique<openscreen::cast::RpcMessage>();
102     rpc->set_handle(type == DemuxerStream::Type::AUDIO
103                         ? receiver_audio_demuxer_stream_handle_
104                         : receiver_video_demuxer_stream_handle_);
105     rpc->set_proc(openscreen::cast::RpcMessage::RPC_DS_INITIALIZE_CALLBACK);
106     auto* init_cb_message = rpc->mutable_demuxerstream_initializecb_rpc();
107     init_cb_message->set_type(type);
108
109     switch (type) {
110       case DemuxerStream::Type::AUDIO: {
111         openscreen::cast::AudioDecoderConfig* audio_message =
112             init_cb_message->mutable_audio_decoder_config();
113         media::cast::ConvertAudioDecoderConfigToProto(audio_config_,
114                                                       audio_message);
115         break;
116       }
117
118       case DemuxerStream::Type::VIDEO: {
119         openscreen::cast::VideoDecoderConfig* video_message =
120             init_cb_message->mutable_video_decoder_config();
121         media::cast::ConvertVideoDecoderConfigToProto(video_config_,
122                                                       video_message);
123         break;
124       }
125
126       default:
127         NOTREACHED();
128     }
129
130     rpc_messenger_->SendMessageToRemote(*rpc);
131   }
132
133   void ReadUntil(DemuxerStream::Type type) {
134     switch (type) {
135       case DemuxerStream::Type::AUDIO:
136         SendAudioFrame();
137         break;
138       case DemuxerStream::Type::VIDEO:
139         SendVideoFrame();
140         break;
141       default:
142         NOTREACHED();
143     }
144   }
145
146   void SendRpcAcquireDemuxer() {
147     auto rpc = std::make_unique<openscreen::cast::RpcMessage>();
148     rpc->set_handle(RpcMessenger::kAcquireDemuxerHandle);
149     rpc->set_proc(openscreen::cast::RpcMessage::RPC_ACQUIRE_DEMUXER);
150     openscreen::cast::AcquireDemuxer* message =
151         rpc->mutable_acquire_demuxer_rpc();
152     message->set_audio_demuxer_handle(sender_audio_demuxer_stream_handle_);
153     message->set_video_demuxer_handle(sender_video_demuxer_stream_handle_);
154     rpc_messenger_->SendMessageToRemote(*rpc);
155   }
156
157   void OnStreamProviderInitialized(PipelineStatus status) {
158     EXPECT_EQ(PIPELINE_OK, status);
159     stream_provider_initialized_ = true;
160     audio_stream_ =
161         stream_provider_->GetFirstStream(DemuxerStream::Type::AUDIO);
162     video_stream_ =
163         stream_provider_->GetFirstStream(DemuxerStream::Type::VIDEO);
164
165     EXPECT_TRUE(audio_stream_);
166     EXPECT_TRUE(video_stream_);
167   }
168
169   void InitializeDemuxer() {
170     DCHECK(stream_provider_);
171     stream_provider_->Initialize(
172         nullptr,
173         base::BindOnce(&StreamProviderTest::OnStreamProviderInitialized,
174                        base::Unretained(this)));
175   }
176
177   void SendAudioFrame() {
178     mock_remotee_->SendAudioFrame(0, audio_buffer_);
179     SendRpcReadUntilCallback(DemuxerStream::Type::AUDIO);
180   }
181
182   void SendVideoFrame() {
183     mock_remotee_->SendVideoFrame(0, video_buffer_);
184     SendRpcReadUntilCallback(DemuxerStream::Type::VIDEO);
185   }
186
187   void SendRpcReadUntilCallback(DemuxerStream::Type type) {
188     // Issues RPC_DS_READUNTIL_CALLBACK RPC message.
189     openscreen::cast::RpcMessage rpc;
190     rpc.set_handle(type == DemuxerStream::Type::AUDIO
191                        ? receiver_audio_demuxer_stream_handle_
192                        : receiver_video_demuxer_stream_handle_);
193     rpc.set_proc(openscreen::cast::RpcMessage::RPC_DS_READUNTIL_CALLBACK);
194     auto* message = rpc.mutable_demuxerstream_readuntilcb_rpc();
195     message->set_count(0);
196     message->set_status(
197         media::cast::ToProtoDemuxerStreamStatus(DemuxerStream::Status::kOk)
198             .value());
199     rpc_messenger_->SendMessageToRemote(rpc);
200   }
201
202   void FlushUntil(uint32_t flush_audio_count, uint32_t flush_video_count) {
203     mock_remotee_->OnFlushUntil(flush_audio_count, flush_video_count);
204   }
205
206   uint32_t GetAudioCurrentFrameCount() {
207     return stream_provider_->audio_stream_->current_frame_count_;
208   }
209
210   uint32_t GetVideoCurrentFrameCount() {
211     return stream_provider_->video_stream_->current_frame_count_;
212   }
213
214   void OnBufferReadFromDemuxerStream(
215       DemuxerStream::Type type,
216       DemuxerStream::Status status,
217       DemuxerStream::DecoderBufferVector buffers) {
218     EXPECT_EQ(status, DemuxerStream::Status::kOk);
219     EXPECT_EQ(buffers.size(), 1u)
220         << "StreamProviderTest only reads a single-buffer.";
221     scoped_refptr<DecoderBuffer> buffer = std::move(buffers[0]);
222     switch (type) {
223       case DemuxerStream::Type::AUDIO:
224         received_audio_buffer_ = buffer;
225         break;
226       case DemuxerStream::Type::VIDEO:
227         received_video_buffer_ = buffer;
228         break;
229       default:
230         NOTREACHED();
231     }
232   }
233
234   base::test::TaskEnvironment task_environment_;
235
236   AudioDecoderConfig audio_config_;
237   VideoDecoderConfig video_config_;
238
239   raw_ptr<DemuxerStream> audio_stream_;
240   raw_ptr<DemuxerStream> video_stream_;
241
242   scoped_refptr<DecoderBuffer> audio_buffer_;
243   scoped_refptr<DecoderBuffer> video_buffer_;
244
245   bool stream_provider_initialized_{false};
246   scoped_refptr<DecoderBuffer> received_audio_buffer_;
247   scoped_refptr<DecoderBuffer> received_video_buffer_;
248
249   int sender_audio_demuxer_stream_handle_ = RpcMessenger::kInvalidHandle;
250   int sender_video_demuxer_stream_handle_ = RpcMessenger::kInvalidHandle;
251   int receiver_audio_demuxer_stream_handle_ = RpcMessenger::kInvalidHandle;
252   int receiver_video_demuxer_stream_handle_ = RpcMessenger::kInvalidHandle;
253
254   raw_ptr<RpcMessenger> rpc_messenger_;
255   raw_ptr<MockReceiverController> mock_controller_;
256   raw_ptr<MockRemotee> mock_remotee_;
257   std::unique_ptr<StreamProvider> stream_provider_;
258 };
259
260 TEST_F(StreamProviderTest, InitializeBeforeRpcAcquireDemuxer) {
261   InitializeDemuxer();
262   EXPECT_FALSE(stream_provider_initialized_);
263
264   SendRpcAcquireDemuxer();
265   task_environment_.RunUntilIdle();
266
267   EXPECT_TRUE(mock_remotee_->audio_stream_.is_bound());
268   EXPECT_TRUE(mock_remotee_->video_stream_.is_bound());
269   EXPECT_TRUE(stream_provider_initialized_);
270
271   // 1 audio stream and 1 video stream
272   EXPECT_EQ(size_t(2), stream_provider_->GetAllStreams().size());
273 }
274
275 TEST_F(StreamProviderTest, InitializeAfterRpcAcquireDemuxer) {
276   SendRpcAcquireDemuxer();
277   EXPECT_FALSE(stream_provider_initialized_);
278
279   InitializeDemuxer();
280   task_environment_.RunUntilIdle();
281
282   EXPECT_TRUE(mock_remotee_->audio_stream_.is_bound());
283   EXPECT_TRUE(mock_remotee_->video_stream_.is_bound());
284   EXPECT_TRUE(stream_provider_initialized_);
285
286   // 1 audio stream and 1 video stream
287   EXPECT_EQ(size_t(2), stream_provider_->GetAllStreams().size());
288 }
289
290 TEST_F(StreamProviderTest, ReadBuffer) {
291   InitializeDemuxer();
292   SendRpcAcquireDemuxer();
293   task_environment_.RunUntilIdle();
294   EXPECT_TRUE(mock_remotee_->audio_stream_.is_bound());
295   EXPECT_TRUE(mock_remotee_->video_stream_.is_bound());
296   EXPECT_TRUE(stream_provider_initialized_);
297
298   audio_stream_->Read(
299       1, base::BindOnce(&StreamProviderTest::OnBufferReadFromDemuxerStream,
300                         base::Unretained(this), DemuxerStream::Type::AUDIO));
301   task_environment_.RunUntilIdle();
302   EXPECT_EQ(audio_buffer_->data_size(), received_audio_buffer_->data_size());
303   EXPECT_EQ(audio_buffer_->end_of_stream(),
304             received_audio_buffer_->end_of_stream());
305   EXPECT_EQ(audio_buffer_->is_key_frame(),
306             received_audio_buffer_->is_key_frame());
307
308   video_stream_->Read(
309       1, base::BindOnce(&StreamProviderTest::OnBufferReadFromDemuxerStream,
310                         base::Unretained(this), DemuxerStream::Type::VIDEO));
311   task_environment_.RunUntilIdle();
312   EXPECT_EQ(video_buffer_->end_of_stream(),
313             received_video_buffer_->end_of_stream());
314 }
315
316 TEST_F(StreamProviderTest, FlushUntil) {
317   InitializeDemuxer();
318   SendRpcAcquireDemuxer();
319   task_environment_.RunUntilIdle();
320   EXPECT_TRUE(mock_remotee_->audio_stream_.is_bound());
321   EXPECT_TRUE(mock_remotee_->video_stream_.is_bound());
322   EXPECT_TRUE(stream_provider_initialized_);
323
324   uint32_t flush_audio_count = 10;
325   uint32_t flush_video_count = 20;
326   FlushUntil(flush_audio_count, flush_video_count);
327   task_environment_.RunUntilIdle();
328
329   EXPECT_EQ(GetAudioCurrentFrameCount(), flush_audio_count);
330   EXPECT_EQ(GetVideoCurrentFrameCount(), flush_video_count);
331 }
332
333 }  // namespace remoting
334 }  // namespace media