Commit 77b42df8 authored by sergeyu's avatar sergeyu Committed by Commit bot

Move audio decoding to protocol layer

Previously ChromotingClient was responsible for creation of
AudioDecodeScheduler. Moved that logic to IceConnectionToHost because
WebrtcConnectionToHost will not need it. Also moved AudioDecodeScheduler
from remoting/client to remoting/protocol and simplified it.

BUG=638505

Review-Url: https://codereview.chromium.org/2384063004
Cr-Commit-Position: refs/heads/master@{#422671}
parent 49a54b59
......@@ -9,8 +9,6 @@ static_library("client") {
sources = [
"audio_consumer.h",
"audio_decode_scheduler.cc",
"audio_decode_scheduler.h",
"audio_player.cc",
"audio_player.h",
"chromoting_client.cc",
......@@ -118,21 +116,6 @@ source_set("opengl_renderer") {
}
}
static_library("test_support") {
testonly = true
sources = [
"fake_audio_consumer.cc",
"fake_audio_consumer.h",
]
public_deps = [
"//remoting/protocol:test_support",
"//testing/gmock",
"//third_party/protobuf:protobuf_lite",
]
}
source_set("unit_tests") {
testonly = true
......@@ -140,7 +123,6 @@ source_set("unit_tests") {
# be compiled on all platforms.
set_sources_assignment_filter([])
sources = [
"audio_decode_scheduler_unittest.cc",
"audio_player_unittest.cc",
"chromoting_client_runtime_unittest.cc",
"client_status_logger_unittest.cc",
......@@ -165,7 +147,6 @@ source_set("unit_tests") {
deps = [
":client",
":test_support",
"//remoting/proto",
"//testing/gmock",
"//testing/gtest",
......
// 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.
#ifndef REMOTING_CLIENT_AUDIO_CONSUMER_H_
#define REMOTING_CLIENT_AUDIO_CONSUMER_H_
#include <memory>
namespace remoting {
class AudioPacket;
class AudioConsumer {
public:
virtual void AddAudioPacket(std::unique_ptr<AudioPacket> packet) = 0;
protected:
virtual ~AudioConsumer() {}
};
} // namespace remoting
#endif // REMOTING_CLIENT_AUDIO_CONSUMER_H_
// Copyright (c) 2012 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 "remoting/client/audio_decode_scheduler.h"
#include <utility>
#include "base/bind.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "remoting/client/audio_consumer.h"
#include "remoting/codec/audio_decoder.h"
#include "remoting/proto/audio.pb.h"
namespace remoting {
class AudioDecodeScheduler::Core : public base::RefCountedThreadSafe<Core> {
public:
Core(scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> audio_decode_task_runner,
base::WeakPtr<AudioConsumer> audio_consumer);
void Initialize(const protocol::SessionConfig& config);
void ProcessAudioPacket(std::unique_ptr<AudioPacket> packet,
const base::Closure& done);
private:
friend class base::RefCountedThreadSafe<Core>;
virtual ~Core();
// Called on the audio decoder thread.
void DecodePacket(std::unique_ptr<AudioPacket> packet,
const base::Closure& done);
// Called on the main thread.
void ProcessDecodedPacket(std::unique_ptr<AudioPacket> packet,
const base::Closure& done);
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> audio_decode_task_runner_;
std::unique_ptr<AudioDecoder> decoder_;
base::WeakPtr<AudioConsumer> audio_consumer_;
DISALLOW_COPY_AND_ASSIGN(Core);
};
AudioDecodeScheduler::Core::Core(
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> audio_decode_task_runner,
base::WeakPtr<AudioConsumer> audio_consumer)
: main_task_runner_(main_task_runner),
audio_decode_task_runner_(audio_decode_task_runner),
audio_consumer_(audio_consumer) {}
AudioDecodeScheduler::Core::~Core() {}
void AudioDecodeScheduler::Core::Initialize(
const protocol::SessionConfig& config) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
decoder_.reset(AudioDecoder::CreateAudioDecoder(config).release());
}
void AudioDecodeScheduler::Core::ProcessAudioPacket(
std::unique_ptr<AudioPacket> packet,
const base::Closure& done) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
audio_decode_task_runner_->PostTask(FROM_HERE, base::Bind(
&AudioDecodeScheduler::Core::DecodePacket, this,
base::Passed(&packet), done));
}
void AudioDecodeScheduler::Core::DecodePacket(
std::unique_ptr<AudioPacket> packet,
const base::Closure& done) {
DCHECK(audio_decode_task_runner_->BelongsToCurrentThread());
std::unique_ptr<AudioPacket> decoded_packet =
decoder_->Decode(std::move(packet));
main_task_runner_->PostTask(FROM_HERE, base::Bind(
&AudioDecodeScheduler::Core::ProcessDecodedPacket, this,
base::Passed(&decoded_packet), done));
}
void AudioDecodeScheduler::Core::ProcessDecodedPacket(
std::unique_ptr<AudioPacket> packet,
const base::Closure& done) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
// Only process |packet| if it is non-null.
if (packet.get() && audio_consumer_) {
audio_consumer_->AddAudioPacket(std::move(packet));
}
done.Run();
}
AudioDecodeScheduler::AudioDecodeScheduler(
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> audio_decode_task_runner,
base::WeakPtr<AudioConsumer> audio_consumer)
: core_(new Core(main_task_runner,
audio_decode_task_runner,
audio_consumer)) {}
AudioDecodeScheduler::~AudioDecodeScheduler() {
}
void AudioDecodeScheduler::Initialize(const protocol::SessionConfig& config) {
core_->Initialize(config);
}
void AudioDecodeScheduler::ProcessAudioPacket(
std::unique_ptr<AudioPacket> packet,
const base::Closure& done) {
core_->ProcessAudioPacket(std::move(packet), done);
}
} // namespace remoting
......@@ -7,6 +7,7 @@
#include <algorithm>
#include <string>
#include "base/callback_helpers.h"
#include "base/logging.h"
#include "base/stl_util.h"
......@@ -19,12 +20,12 @@ AudioPlayer::AudioPlayer()
: sampling_rate_(AudioPacket::SAMPLING_RATE_INVALID),
start_failed_(false),
queued_bytes_(0),
bytes_consumed_(0) {
}
bytes_consumed_(0) {}
AudioPlayer::~AudioPlayer() {}
void AudioPlayer::AddAudioPacket(std::unique_ptr<AudioPacket> packet) {
void AudioPlayer::ProcessAudioPacket(std::unique_ptr<AudioPacket> packet,
const base::Closure& done) {
CHECK_EQ(1, packet->data_size());
DCHECK_EQ(AudioPacket::ENCODING_RAW, packet->encoding());
DCHECK_NE(AudioPacket::SAMPLING_RATE_INVALID, packet->sampling_rate());
......@@ -32,6 +33,8 @@ void AudioPlayer::AddAudioPacket(std::unique_ptr<AudioPacket> packet) {
DCHECK_EQ(kChannels, static_cast<int>(packet->channels()));
DCHECK_EQ(packet->data(0).size() % (kChannels * kSampleSizeBytes), 0u);
base::ScopedClosureRunner done_runner(done);
// No-op if the Pepper player won't start.
if (start_failed_) {
return;
......
......@@ -13,12 +13,12 @@
#include "base/macros.h"
#include "base/synchronization/lock.h"
#include "remoting/client/audio_consumer.h"
#include "remoting/proto/audio.pb.h"
#include "remoting/protocol/audio_stub.h"
namespace remoting {
class AudioPlayer : public AudioConsumer {
class AudioPlayer : public protocol::AudioStub {
public:
// The number of channels in the audio stream (only supporting stereo audio
// for now).
......@@ -27,8 +27,9 @@ class AudioPlayer : public AudioConsumer {
~AudioPlayer() override;
// AudioConsumer implementation.
void AddAudioPacket(std::unique_ptr<AudioPacket> packet) override;
// protocol::AudioStub implementation.
void ProcessAudioPacket(std::unique_ptr<AudioPacket> packet,
const base::Closure& done) override;
protected:
AudioPlayer();
......
......@@ -8,6 +8,7 @@
#include <memory>
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -117,28 +118,28 @@ std::unique_ptr<AudioPacket> CreatePacket48000Hz(int samples) {
TEST_F(AudioPlayerTest, Init) {
ASSERT_EQ(0, GetNumQueuedPackets());
audio_->AddAudioPacket(CreatePacket44100Hz(10));
audio_->ProcessAudioPacket(CreatePacket44100Hz(10), base::Closure());
ASSERT_EQ(1, GetNumQueuedPackets());
}
TEST_F(AudioPlayerTest, MultipleSamples) {
audio_->AddAudioPacket(CreatePacket44100Hz(10));
audio_->ProcessAudioPacket(CreatePacket44100Hz(10), base::Closure());
ASSERT_EQ(10, GetNumQueuedSamples());
ASSERT_EQ(1, GetNumQueuedPackets());
audio_->AddAudioPacket(CreatePacket44100Hz(20));
audio_->ProcessAudioPacket(CreatePacket44100Hz(20), base::Closure());
ASSERT_EQ(30, GetNumQueuedSamples());
ASSERT_EQ(2, GetNumQueuedPackets());
}
TEST_F(AudioPlayerTest, ChangeSampleRate) {
audio_->AddAudioPacket(CreatePacket44100Hz(10));
audio_->ProcessAudioPacket(CreatePacket44100Hz(10), base::Closure());
ASSERT_EQ(10, GetNumQueuedSamples());
ASSERT_EQ(1, GetNumQueuedPackets());
// New packet with different sampling rate causes previous samples to
// be removed.
audio_->AddAudioPacket(CreatePacket48000Hz(20));
audio_->ProcessAudioPacket(CreatePacket48000Hz(20), base::Closure());
ASSERT_EQ(20, GetNumQueuedSamples());
ASSERT_EQ(1, GetNumQueuedPackets());
}
......@@ -146,7 +147,7 @@ TEST_F(AudioPlayerTest, ChangeSampleRate) {
TEST_F(AudioPlayerTest, ExceedLatency) {
// Push about 4 seconds worth of samples.
for (int i = 0; i < 100; ++i) {
audio_->AddAudioPacket(CreatePacket48000Hz(2000));
audio_->ProcessAudioPacket(CreatePacket48000Hz(2000), base::Closure());
}
// Verify that we don't have more than 0.5s.
......@@ -162,7 +163,8 @@ TEST_F(AudioPlayerTest, ConsumePartialPacket) {
// Process 100 samples.
int packet1_samples = 100;
total_samples += packet1_samples;
audio_->AddAudioPacket(CreatePacket44100Hz(packet1_samples));
audio_->ProcessAudioPacket(CreatePacket44100Hz(packet1_samples),
base::Closure());
ASSERT_EQ(total_samples, GetNumQueuedSamples());
ASSERT_EQ(1, GetNumQueuedPackets());
ASSERT_EQ(bytes_consumed, GetBytesConsumed());
......@@ -190,13 +192,15 @@ TEST_F(AudioPlayerTest, ConsumeAcrossPackets) {
// Packet 1.
int packet1_samples = 20;
total_samples += packet1_samples;
audio_->AddAudioPacket(CreatePacket44100Hz(packet1_samples));
audio_->ProcessAudioPacket(CreatePacket44100Hz(packet1_samples),
base::Closure());
ASSERT_EQ(total_samples, GetNumQueuedSamples());
// Packet 2.
int packet2_samples = 70;
total_samples += packet2_samples;
audio_->AddAudioPacket(CreatePacket44100Hz(packet2_samples));
audio_->ProcessAudioPacket(CreatePacket44100Hz(packet2_samples),
base::Closure());
ASSERT_EQ(total_samples, GetNumQueuedSamples());
ASSERT_EQ(bytes_consumed, GetBytesConsumed());
......@@ -233,14 +237,16 @@ TEST_F(AudioPlayerTest, ConsumeEntirePacket) {
// Packet 1.
int packet1_samples = 50;
total_samples += packet1_samples;
audio_->AddAudioPacket(CreatePacket44100Hz(packet1_samples));
audio_->ProcessAudioPacket(CreatePacket44100Hz(packet1_samples),
base::Closure());
ASSERT_EQ(total_samples, GetNumQueuedSamples());
ASSERT_EQ(bytes_consumed, GetBytesConsumed());
// Packet 2.
int packet2_samples = 30;
total_samples += packet2_samples;
audio_->AddAudioPacket(CreatePacket44100Hz(packet2_samples));
audio_->ProcessAudioPacket(CreatePacket44100Hz(packet2_samples),
base::Closure());
ASSERT_EQ(total_samples, GetNumQueuedSamples());
ASSERT_EQ(bytes_consumed, GetBytesConsumed());
......@@ -299,7 +305,8 @@ TEST_F(AudioPlayerTest, NotEnoughDataToConsume) {
// Packet 1.
int packet1_samples = 10;
total_samples += packet1_samples;
audio_->AddAudioPacket(CreatePacket44100Hz(packet1_samples));
audio_->ProcessAudioPacket(CreatePacket44100Hz(packet1_samples),
base::Closure());
ASSERT_EQ(total_samples, GetNumQueuedSamples());
ASSERT_EQ(bytes_consumed, GetBytesConsumed());
......
......@@ -9,8 +9,6 @@
#include "base/memory/ptr_util.h"
#include "remoting/base/capabilities.h"
#include "remoting/base/constants.h"
#include "remoting/client/audio_consumer.h"
#include "remoting/client/audio_decode_scheduler.h"
#include "remoting/client/client_context.h"
#include "remoting/client/client_user_interface.h"
#include "remoting/protocol/authenticator.h"
......@@ -28,17 +26,16 @@
namespace remoting {
ChromotingClient::ChromotingClient(ClientContext* client_context,
ClientUserInterface* user_interface,
protocol::VideoRenderer* video_renderer,
base::WeakPtr<AudioConsumer> audio_consumer)
ChromotingClient::ChromotingClient(
ClientContext* client_context,
ClientUserInterface* user_interface,
protocol::VideoRenderer* video_renderer,
base::WeakPtr<protocol::AudioStub> audio_consumer)
: user_interface_(user_interface), video_renderer_(video_renderer) {
DCHECK(client_context->main_task_runner()->BelongsToCurrentThread());
if (audio_consumer) {
audio_decode_scheduler_.reset(new AudioDecodeScheduler(
client_context->main_task_runner(),
client_context->audio_decode_task_runner(), audio_consumer));
}
audio_decode_task_runner_ = client_context->audio_decode_task_runner();
audio_consumer_ = audio_consumer;
}
ChromotingClient::~ChromotingClient() {
......@@ -70,7 +67,7 @@ void ChromotingClient::Start(
if (!protocol_config_)
protocol_config_ = protocol::CandidateSessionConfig::CreateDefault();
if (!audio_decode_scheduler_)
if (!audio_consumer_)
protocol_config_->DisableAudioChannel();
if (!connection_) {
......@@ -89,7 +86,8 @@ void ChromotingClient::Start(
connection_->set_client_stub(this);
connection_->set_clipboard_stub(this);
connection_->set_video_renderer(video_renderer_);
connection_->set_audio_stub(audio_decode_scheduler_.get());
connection_->InitializeAudio(audio_decode_task_runner_, audio_consumer_);
session_manager_.reset(new protocol::JingleSessionManager(signal_strategy));
session_manager_->set_protocol_config(std::move(protocol_config_));
......@@ -199,9 +197,7 @@ void ChromotingClient::OnConnectionState(
DCHECK(thread_checker_.CalledOnValidThread());
VLOG(1) << "ChromotingClient::OnConnectionState(" << state << ")";
if (state == protocol::ConnectionToHost::AUTHENTICATED) {
OnAuthenticated();
} else if (state == protocol::ConnectionToHost::CONNECTED) {
if (state == protocol::ConnectionToHost::CONNECTED) {
OnChannelsConnected();
}
user_interface_->OnConnectionState(state, error);
......@@ -253,14 +249,6 @@ void ChromotingClient::StartConnection() {
transport_context_, this);
}
void ChromotingClient::OnAuthenticated() {
DCHECK(thread_checker_.CalledOnValidThread());
// Initialize the decoder.
if (connection_->config().is_audio_enabled())
audio_decode_scheduler_->Initialize(connection_->config());
}
void ChromotingClient::OnChannelsConnected() {
DCHECK(thread_checker_.CalledOnValidThread());
......
......@@ -37,7 +37,6 @@ class TransportContext;
class VideoRenderer;
} // namespace protocol
class AudioConsumer;
class AudioDecodeScheduler;
class ClientContext;
class ClientUserInterface;
......@@ -53,7 +52,7 @@ class ChromotingClient : public SignalStrategy::Listener,
ChromotingClient(ClientContext* client_context,
ClientUserInterface* user_interface,
protocol::VideoRenderer* video_renderer,
base::WeakPtr<AudioConsumer> audio_consumer);
base::WeakPtr<protocol::AudioStub> audio_consumer);
~ChromotingClient() override;
......@@ -110,19 +109,19 @@ class ChromotingClient : public SignalStrategy::Listener,
// Starts connection once |signal_strategy_| is connected.
void StartConnection();
// Called when the connection is authenticated.
void OnAuthenticated();
// Called when all channels are connected.
void OnChannelsConnected();
base::ThreadChecker thread_checker_;
scoped_refptr<base::SingleThreadTaskRunner> audio_decode_task_runner_;
std::unique_ptr<protocol::CandidateSessionConfig> protocol_config_;
// The following are not owned by this class.
ClientUserInterface* user_interface_ = nullptr;
protocol::VideoRenderer* video_renderer_ = nullptr;
base::WeakPtr<protocol::AudioStub> audio_consumer_;
SignalStrategy* signal_strategy_ = nullptr;
std::string host_jid_;
......@@ -134,8 +133,6 @@ class ChromotingClient : public SignalStrategy::Listener,
protocol::MouseInputFilter mouse_input_scaler_;
std::unique_ptr<AudioDecodeScheduler> audio_decode_scheduler_;
std::string local_capabilities_;
// The set of all capabilities supported by the host.
......
// 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 "remoting/client/fake_audio_consumer.h"
#include "remoting/proto/audio.pb.h"
namespace remoting {
FakeAudioConsumer::FakeAudioConsumer() : weak_factory_(this) {}
FakeAudioConsumer::~FakeAudioConsumer() {}
void FakeAudioConsumer::AddAudioPacket(std::unique_ptr<AudioPacket> packet) {}
base::WeakPtr<FakeAudioConsumer> FakeAudioConsumer::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
} // namespace remoting
// 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.
#ifndef REMOTING_CLIENT_FAKE_AUDIO_CONSUMER_H_
#define REMOTING_CLIENT_FAKE_AUDIO_CONSUMER_H_
#include <memory>
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "remoting/client/audio_consumer.h"
namespace remoting {
class FakeAudioConsumer : public AudioConsumer {
public:
FakeAudioConsumer();
~FakeAudioConsumer() override;
base::WeakPtr<FakeAudioConsumer> GetWeakPtr();
// AudioConsumer implementation.
void AddAudioPacket(std::unique_ptr<AudioPacket> packet) override;
private:
base::WeakPtrFactory<FakeAudioConsumer> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(FakeAudioConsumer);
};
} // namespace remoting
#endif // REMOTING_CLIENT_FAKE_AUDIO_CONSUMER_H_
......@@ -6,6 +6,8 @@ import("//build/config/features.gni")
static_library("protocol") {
sources = [
"audio_decode_scheduler.cc",
"audio_decode_scheduler.h",
"audio_pump.cc",
"audio_pump.h",
"audio_reader.cc",
......@@ -273,6 +275,7 @@ source_set("unit_tests") {
testonly = true
sources = [
"audio_decode_scheduler_unittest.cc",
"audio_pump_unittest.cc",
"authenticator_test_base.cc",
"authenticator_test_base.h",
......
// 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 "remoting/protocol/audio_decode_scheduler.h"
#include <utility>
#include "base/bind.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/task_runner_util.h"
#include "remoting/codec/audio_decoder.h"
#include "remoting/proto/audio.pb.h"
#include "remoting/protocol/audio_stub.h"
namespace remoting {
namespace protocol {
AudioDecodeScheduler::AudioDecodeScheduler(
scoped_refptr<base::SingleThreadTaskRunner> audio_decode_task_runner,
base::WeakPtr<protocol::AudioStub> audio_consumer)
: audio_decode_task_runner_(audio_decode_task_runner),
audio_consumer_(audio_consumer),
weak_factory_(this) {}
AudioDecodeScheduler::~AudioDecodeScheduler() {
audio_decode_task_runner_->DeleteSoon(FROM_HERE, decoder_.release());
}
void AudioDecodeScheduler::Initialize(const protocol::SessionConfig& config) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(!decoder_);
decoder_.reset(AudioDecoder::CreateAudioDecoder(config).release());
}
void AudioDecodeScheduler::ProcessAudioPacket(
std::unique_ptr<AudioPacket> packet,
const base::Closure& done) {
DCHECK(thread_checker_.CalledOnValidThread());
base::PostTaskAndReplyWithResult(
audio_decode_task_runner_.get(), FROM_HERE,
base::Bind(&AudioDecoder::Decode, base::Unretained(decoder_.get()),
base::Passed(&packet)),
base::Bind(&AudioDecodeScheduler::ProcessDecodedPacket,
weak_factory_.GetWeakPtr(), done));
}
void AudioDecodeScheduler::ProcessDecodedPacket(
const base::Closure& done,
std::unique_ptr<AudioPacket> packet) {
DCHECK(thread_checker_.CalledOnValidThread());
if (!packet || !audio_consumer_) {
done.Run();
return;
}
audio_consumer_->ProcessAudioPacket(std::move(packet), done);
}
} // namespace protocol
} // namespace remoting
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// 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.
#ifndef REMOTING_CLIENT_AUDIO_DECODE_SCHEDULER_H_
#define REMOTING_CLIENT_AUDIO_DECODE_SCHEDULER_H_
#ifndef REMOTING_PROTOCOL_AUDIO_DECODE_SCHEDULER_H_
#define REMOTING_PROTOCOL_AUDIO_DECODE_SCHEDULER_H_
#include <memory>
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
#include "remoting/protocol/audio_stub.h"
namespace base {
......@@ -18,20 +19,19 @@ class SingleThreadTaskRunner;
namespace remoting {
namespace protocol {
class SessionConfig;
} // namespace protocol
class AudioConsumer;
class AudioDecoder;
class AudioPacket;
class AudioDecodeScheduler : public protocol::AudioStub {
namespace protocol {
class SessionConfig;
class AudioStub;
class AudioDecodeScheduler : public AudioStub {
public:
AudioDecodeScheduler(
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> audio_decode_task_runner,
base::WeakPtr<AudioConsumer> audio_consumer);
base::WeakPtr<AudioStub> audio_consumer);
~AudioDecodeScheduler() override;
// Initializes decoder with the information from the protocol config.
......@@ -42,13 +42,23 @@ class AudioDecodeScheduler : public protocol::AudioStub {
const base::Closure& done) override;
private:
class Core;
void ProcessDecodedPacket(const base::Closure& done,
std::unique_ptr<AudioPacket> packet);
scoped_refptr<base::SingleThreadTaskRunner> audio_decode_task_runner_;
base::WeakPtr<AudioStub> audio_consumer_;
scoped_refptr<Core> core_;
// Decoder used on the audio thread.
std::unique_ptr<AudioDecoder> decoder_;
base::ThreadChecker thread_checker_;
base::WeakPtrFactory<AudioDecodeScheduler> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(AudioDecodeScheduler);
};
} // namespace protocol
} // namespace remoting
#endif // REMOTING_CLIENT_AUDIO_DECODE_SCHEDULER_H_
#endif // REMOTING_PROTOCOL_AUDIO_DECODE_SCHEDULER_H_
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "remoting/client/audio_decode_scheduler.h"
#include "remoting/protocol/audio_decode_scheduler.h"
#include "base/bind.h"
#include "base/message_loop/message_loop.h"
......@@ -10,19 +10,41 @@
#include "base/threading/thread.h"
#include "remoting/base/auto_thread.h"
#include "remoting/base/auto_thread_task_runner.h"
#include "remoting/client/fake_audio_consumer.h"
#include "remoting/proto/audio.pb.h"
#include "remoting/protocol/session_config.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace remoting {
namespace protocol {
namespace {
const int kAudioSampleBytes = 4;
const uint8_t kDummyAudioData = 0x8B;
} // namespace
class FakeAudioConsumer : public AudioStub {
public:
FakeAudioConsumer(): weak_factory_(this) {}
~FakeAudioConsumer() override {}
namespace remoting {
base::WeakPtr<FakeAudioConsumer> GetWeakPtr(){
return weak_factory_.GetWeakPtr();
}