blob: 109945eefe343c03570d02379d346f28e874bed6 [file] [log] [blame]
// Copyright 2016 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/fake_remoter.h"
#include <memory>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/buildflag.h"
#include "media/media_buildflags.h"
#include "media/remoting/renderer_controller.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "testing/gtest/include/gtest/gtest.h"
#if BUILDFLAG(ENABLE_MEDIA_REMOTING_RPC)
#include "media/remoting/proto_utils.h" // nogncheck
#endif
namespace media {
namespace remoting {
FakeRemotingDataStreamSender::FakeRemotingDataStreamSender(
mojo::PendingReceiver<mojom::RemotingDataStreamSender> stream_sender,
mojo::ScopedDataPipeConsumerHandle consumer_handle)
: receiver_(this, std::move(stream_sender)),
data_pipe_reader_(std::move(consumer_handle)),
send_frame_count_(0),
cancel_in_flight_count_(0) {}
FakeRemotingDataStreamSender::~FakeRemotingDataStreamSender() = default;
void FakeRemotingDataStreamSender::ResetHistory() {
send_frame_count_ = 0;
cancel_in_flight_count_ = 0;
next_frame_data_.resize(0);
received_frame_list.clear();
}
bool FakeRemotingDataStreamSender::ValidateFrameBuffer(size_t index,
size_t size,
bool key_frame,
int pts_ms) {
if (index >= received_frame_list.size()) {
VLOG(1) << "There is no such frame";
return false;
}
#if BUILDFLAG(ENABLE_MEDIA_REMOTING_RPC)
const std::vector<uint8_t>& data = received_frame_list[index];
scoped_refptr<DecoderBuffer> media_buffer =
ByteArrayToDecoderBuffer(data.data(), data.size());
// Checks if pts is correct or not
if (media_buffer->timestamp().InMilliseconds() != pts_ms) {
VLOG(1) << "Pts should be:" << pts_ms << "("
<< media_buffer->timestamp().InMilliseconds() << ")";
return false;
}
// Checks if key frame is set correct or not
if (media_buffer->is_key_frame() != key_frame) {
VLOG(1) << "Key frame should be:" << key_frame << "("
<< media_buffer->is_key_frame() << ")";
return false;
}
// Checks if frame buffer size is correct or not
if (media_buffer->data_size() != size) {
VLOG(1) << "Buffer size should be:" << size << "("
<< media_buffer->data_size() << ")";
return false;
}
// Checks if frame buffer is correct or not.
bool return_value = true;
const uint8_t* buffer = media_buffer->data();
for (size_t i = 0; i < media_buffer->data_size(); ++i) {
uint32_t value = static_cast<uint32_t>(i & 0xFF);
if (value != static_cast<uint32_t>(buffer[i])) {
VLOG(1) << "buffer index: " << i << " should be "
<< static_cast<uint32_t>(value) << " ("
<< static_cast<uint32_t>(buffer[i]) << ")";
return_value = false;
}
}
return return_value;
#else
return true;
#endif // BUILDFLAG(ENABLE_MEDIA_REMOTING_RPC)
}
void FakeRemotingDataStreamSender::SendFrame(uint32_t frame_size) {
next_frame_data_.resize(frame_size);
data_pipe_reader_.Read(
next_frame_data_.data(), frame_size,
base::BindOnce(&FakeRemotingDataStreamSender::OnFrameRead,
base::Unretained(this)));
}
void FakeRemotingDataStreamSender::OnFrameRead(bool success) {
EXPECT_TRUE(success);
++send_frame_count_;
received_frame_list.push_back(std::move(next_frame_data_));
EXPECT_EQ(send_frame_count_, received_frame_list.size());
}
void FakeRemotingDataStreamSender::CancelInFlightData() {
++cancel_in_flight_count_;
}
FakeRemoter::FakeRemoter(mojo::PendingRemote<mojom::RemotingSource> source,
bool start_will_fail)
: source_(std::move(source)), start_will_fail_(start_will_fail) {}
FakeRemoter::~FakeRemoter() = default;
void FakeRemoter::Start() {
if (start_will_fail_) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&FakeRemoter::StartFailed, weak_factory_.GetWeakPtr()));
} else {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&FakeRemoter::Started, weak_factory_.GetWeakPtr()));
}
}
void FakeRemoter::StartDataStreams(
mojo::ScopedDataPipeConsumerHandle audio_pipe,
mojo::ScopedDataPipeConsumerHandle video_pipe,
mojo::PendingReceiver<mojom::RemotingDataStreamSender> audio_sender,
mojo::PendingReceiver<mojom::RemotingDataStreamSender> video_sender) {
if (audio_pipe.is_valid()) {
VLOG(2) << "Has audio";
audio_stream_sender_.reset(new FakeRemotingDataStreamSender(
std::move(audio_sender), std::move(audio_pipe)));
}
if (video_pipe.is_valid()) {
VLOG(2) << "Has video";
video_stream_sender_.reset(new FakeRemotingDataStreamSender(
std::move(video_sender), std::move(video_pipe)));
}
}
void FakeRemoter::Stop(mojom::RemotingStopReason reason) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&FakeRemoter::Stopped,
weak_factory_.GetWeakPtr(), reason));
}
void FakeRemoter::SendMessageToSink(const std::vector<uint8_t>& message) {}
void FakeRemoter::EstimateTransmissionCapacity(
mojom::Remoter::EstimateTransmissionCapacityCallback callback) {
std::move(callback).Run(10000000 / 8.0);
}
void FakeRemoter::Started() {
source_->OnStarted();
}
void FakeRemoter::StartFailed() {
source_->OnStartFailed(mojom::RemotingStartFailReason::ROUTE_TERMINATED);
}
void FakeRemoter::Stopped(mojom::RemotingStopReason reason) {
source_->OnStopped(reason);
}
FakeRemoterFactory::FakeRemoterFactory(bool start_will_fail)
: start_will_fail_(start_will_fail) {}
FakeRemoterFactory::~FakeRemoterFactory() = default;
void FakeRemoterFactory::Create(
mojo::PendingRemote<mojom::RemotingSource> source,
mojo::PendingReceiver<mojom::Remoter> receiver) {
mojo::MakeSelfOwnedReceiver(
std::make_unique<FakeRemoter>(std::move(source), start_will_fail_),
std::move(receiver));
}
// static
std::unique_ptr<RendererController> FakeRemoterFactory::CreateController(
bool start_will_fail) {
mojo::PendingRemote<mojom::RemotingSource> remoting_source;
auto remoting_source_receiver =
remoting_source.InitWithNewPipeAndPassReceiver();
mojo::PendingRemote<mojom::Remoter> remoter;
FakeRemoterFactory remoter_factory(start_will_fail);
remoter_factory.Create(std::move(remoting_source),
remoter.InitWithNewPipeAndPassReceiver());
return std::make_unique<RendererController>(
std::move(remoting_source_receiver), std::move(remoter));
}
} // namespace remoting
} // namespace media