Commit 22d7f3b7 authored by kxing@chromium.org's avatar kxing@chromium.org

Piping for audio decoding.


Review URL: https://chromiumcodereview.appspot.com/10843031

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@149990 0039d316-1c4b-4281-b951-d872f2087c98
parent f6d95185
......@@ -3,6 +3,7 @@ include_rules = [
"+jingle/glue",
"+net",
"+remoting/codec",
"+remoting/protocol",
"+remoting/jingle_glue",
]
// 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 "base/bind.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "remoting/client/audio_player.h"
#include "remoting/codec/audio_decoder.h"
#include "remoting/proto/audio.pb.h"
namespace remoting {
AudioDecodeScheduler::AudioDecodeScheduler(
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> audio_decode_task_runner,
scoped_ptr<AudioPlayer> audio_player)
: main_task_runner_(main_task_runner),
audio_decode_task_runner_(audio_decode_task_runner),
audio_player_(audio_player.Pass()) {
}
AudioDecodeScheduler::~AudioDecodeScheduler() {
}
void AudioDecodeScheduler::Initialize(const protocol::SessionConfig& config) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
decoder_.reset(AudioDecoder::CreateAudioDecoder(config).release());
}
void AudioDecodeScheduler::ProcessAudioPacket(scoped_ptr<AudioPacket> packet,
const base::Closure& done) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
audio_decode_task_runner_->PostTask(FROM_HERE, base::Bind(
&AudioDecodeScheduler::DecodePacket, base::Unretained(this),
base::Passed(&packet), done));
}
void AudioDecodeScheduler::DecodePacket(scoped_ptr<AudioPacket> packet,
const base::Closure& done) {
DCHECK(audio_decode_task_runner_->BelongsToCurrentThread());
scoped_ptr<AudioPacket> decoded_packet = decoder_->Decode(packet.Pass());
main_task_runner_->PostTask(FROM_HERE, base::Bind(
&AudioDecodeScheduler::ProcessDecodedPacket, base::Unretained(this),
base::Passed(decoded_packet.Pass()), done));
}
void AudioDecodeScheduler::ProcessDecodedPacket(scoped_ptr<AudioPacket> packet,
const base::Closure& done) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
audio_player_->ProcessAudioPacket(packet.Pass());
done.Run();
}
} // namespace remoting
// 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.
#ifndef REMOTING_CLIENT_AUDIO_DECODE_SCHEDULER_H_
#define REMOTING_CLIENT_AUDIO_DECODE_SCHEDULER_H_
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "remoting/protocol/audio_stub.h"
namespace base {
class SingleThreadTaskRunner;
} // namespace base
namespace remoting {
namespace protocol {
class SessionConfig;
} // namespace protocol
class AudioDecoder;
class AudioPacket;
class AudioPlayer;
class AudioDecodeScheduler : public protocol::AudioStub {
public:
AudioDecodeScheduler(
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> audio_decode_task_runner,
scoped_ptr<AudioPlayer> audio_player);
virtual ~AudioDecodeScheduler();
// Initializes decoder with the information from the protocol config.
void Initialize(const protocol::SessionConfig& config);
// AudioStub implementation.
virtual void ProcessAudioPacket(scoped_ptr<AudioPacket> packet,
const base::Closure& done) OVERRIDE;
private:
// Called on the audio decoder thread.
void DecodePacket(scoped_ptr<AudioPacket> packet, const base::Closure& done);
// Called on the main thread.
void ProcessDecodedPacket(scoped_ptr<AudioPacket> packet,
const base::Closure& done);
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> audio_decode_task_runner_;
scoped_ptr<AudioDecoder> decoder_;
scoped_ptr<AudioPlayer> audio_player_;
DISALLOW_COPY_AND_ASSIGN(AudioDecodeScheduler);
};
} // namespace remoting
#endif // REMOTING_CLIENT_AUDIO_DECODE_SCHEDULER_H_
......@@ -5,6 +5,7 @@
#include "remoting/client/chromoting_client.h"
#include "base/bind.h"
#include "remoting/client/audio_decode_scheduler.h"
#include "remoting/client/audio_player.h"
#include "remoting/client/client_context.h"
#include "remoting/client/client_user_interface.h"
......@@ -31,20 +32,23 @@ ChromotingClient::QueuedVideoPacket::~QueuedVideoPacket() {
ChromotingClient::ChromotingClient(
const ClientConfig& config,
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
ClientContext* client_context,
protocol::ConnectionToHost* connection,
ClientUserInterface* user_interface,
RectangleUpdateDecoder* rectangle_decoder,
AudioPlayer* audio_player)
scoped_ptr<AudioPlayer> audio_player)
: config_(config),
task_runner_(task_runner),
task_runner_(client_context->main_task_runner()),
connection_(connection),
user_interface_(user_interface),
rectangle_decoder_(rectangle_decoder),
audio_player_(audio_player),
packet_being_processed_(false),
last_sequence_number_(0),
weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
audio_decode_scheduler_.reset(new AudioDecodeScheduler(
client_context->main_task_runner(),
client_context->audio_decode_task_runner(),
audio_player.Pass()));
}
ChromotingClient::~ChromotingClient() {
......@@ -65,7 +69,8 @@ void ChromotingClient::Start(
connection_->Connect(xmpp_proxy, config_.local_jid, config_.host_jid,
config_.host_public_key, transport_factory.Pass(),
authenticator.Pass(), this, this, this, this, this);
authenticator.Pass(), this, this, this, this,
audio_decode_scheduler_.get());
}
void ChromotingClient::Stop(const base::Closure& shutdown_task) {
......@@ -141,12 +146,6 @@ int ChromotingClient::GetPendingVideoPackets() {
return received_packets_.size();
}
void ChromotingClient::ProcessAudioPacket(scoped_ptr<AudioPacket> packet,
const base::Closure& done) {
audio_player_->ProcessAudioPacket(packet.Pass());
done.Run();
}
void ChromotingClient::DispatchPacket() {
DCHECK(task_runner_->BelongsToCurrentThread());
CHECK(!packet_being_processed_);
......@@ -217,6 +216,8 @@ void ChromotingClient::Initialize() {
// Initialize the decoder.
rectangle_decoder_->Initialize(connection_->config());
if (connection_->config().is_audio_enabled())
audio_decode_scheduler_->Initialize(connection_->config());
}
} // namespace remoting
......@@ -15,7 +15,6 @@
#include "base/time.h"
#include "remoting/client/client_config.h"
#include "remoting/client/chromoting_stats.h"
#include "remoting/protocol/audio_stub.h"
#include "remoting/protocol/client_stub.h"
#include "remoting/protocol/clipboard_stub.h"
#include "remoting/protocol/connection_to_host.h"
......@@ -33,23 +32,24 @@ namespace protocol {
class TransportFactory;
} // namespace protocol
class AudioDecodeScheduler;
class AudioPlayer;
class ClientContext;
class ClientUserInterface;
class RectangleUpdateDecoder;
// TODO(sergeyu): Move VideoStub implementation to RectangleUpdateDecoder.
class ChromotingClient : public protocol::ConnectionToHost::HostEventCallback,
public protocol::ClientStub,
public protocol::VideoStub,
public protocol::AudioStub {
public protocol::VideoStub {
public:
// Objects passed in are not owned by this class.
ChromotingClient(const ClientConfig& config,
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
ClientContext* client_context,
protocol::ConnectionToHost* connection,
ClientUserInterface* user_interface,
RectangleUpdateDecoder* rectangle_decoder,
AudioPlayer* audio_player);
scoped_ptr<AudioPlayer> audio_player);
virtual ~ChromotingClient();
......@@ -80,10 +80,6 @@ class ChromotingClient : public protocol::ConnectionToHost::HostEventCallback,
const base::Closure& done) OVERRIDE;
virtual int GetPendingVideoPackets() OVERRIDE;
// AudioStub implementation.
virtual void ProcessAudioPacket(scoped_ptr<AudioPacket> packet,
const base::Closure& done) OVERRIDE;
private:
struct QueuedVideoPacket {
QueuedVideoPacket(scoped_ptr<VideoPacket> packet,
......@@ -112,8 +108,10 @@ class ChromotingClient : public protocol::ConnectionToHost::HostEventCallback,
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
protocol::ConnectionToHost* connection_;
ClientUserInterface* user_interface_;
// TODO(kxing): Make ChromotingClient own RectangleUpdateDecoder.
RectangleUpdateDecoder* rectangle_decoder_;
AudioPlayer* audio_player_;
scoped_ptr<AudioDecodeScheduler> audio_decode_scheduler_;
// If non-NULL, this is called when the client is done.
base::Closure client_done_;
......
......@@ -8,7 +8,8 @@ namespace remoting {
ClientContext::ClientContext(base::SingleThreadTaskRunner* main_task_runner)
: main_task_runner_(main_task_runner),
decode_thread_("ChromotingClientDecodeThread") {
decode_thread_("ChromotingClientDecodeThread"),
audio_decode_thread_("ChromotingClientAudioDecodeThread") {
}
ClientContext::~ClientContext() {
......@@ -17,11 +18,13 @@ ClientContext::~ClientContext() {
void ClientContext::Start() {
// Start all the threads.
decode_thread_.Start();
audio_decode_thread_.Start();
}
void ClientContext::Stop() {
// Stop all the threads.
decode_thread_.Stop();
audio_decode_thread_.Stop();
}
base::SingleThreadTaskRunner* ClientContext::main_task_runner() {
......@@ -32,4 +35,8 @@ base::SingleThreadTaskRunner* ClientContext::decode_task_runner() {
return decode_thread_.message_loop_proxy();
}
base::SingleThreadTaskRunner* ClientContext::audio_decode_task_runner() {
return audio_decode_thread_.message_loop_proxy();
}
} // namespace remoting
......@@ -29,13 +29,17 @@ class ClientContext {
base::SingleThreadTaskRunner* main_task_runner();
base::SingleThreadTaskRunner* decode_task_runner();
base::SingleThreadTaskRunner* audio_decode_task_runner();
private:
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
// A thread that handles all decode operations.
// A thread that handles all video decode operations.
base::Thread decode_thread_;
// A thread that handles all audio decode operations.
base::Thread audio_decode_thread_;
DISALLOW_COPY_AND_ASSIGN(ClientContext);
};
......
......@@ -470,11 +470,11 @@ void ChromotingInstance::Connect(const ClientConfig& config) {
jingle_glue::JingleThreadWrapper::EnsureForCurrentThread();
host_connection_.reset(new protocol::ConnectionToHost(true));
audio_player_.reset(new PepperAudioPlayer(this));
client_.reset(new ChromotingClient(config, context_.main_task_runner(),
scoped_ptr<AudioPlayer> audio_player(new PepperAudioPlayer(this));
client_.reset(new ChromotingClient(config, &context_,
host_connection_.get(), this,
rectangle_decoder_.get(),
audio_player_.get()));
audio_player.Pass()));
// Construct the input pipeline
mouse_input_filter_.reset(
......@@ -536,7 +536,6 @@ void ChromotingInstance::Disconnect() {
input_handler_.reset();
input_tracker_.reset();
mouse_input_filter_.reset();
audio_player_.reset();
host_connection_.reset();
}
......
......@@ -199,7 +199,6 @@ class ChromotingInstance :
#endif
KeyEventMapper key_mapper_;
scoped_ptr<PepperInputHandler> input_handler_;
scoped_ptr<PepperAudioPlayer> audio_player_;
scoped_ptr<ChromotingClient> client_;
// XmppProxy is a refcounted interface used to perform thread-switching and
......
include_rules = [
"+google/protobuf",
"+remoting/protocol",
]
// 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/codec/audio_decoder.h"
#include "base/logging.h"
#include "remoting/codec/audio_decoder_verbatim.h"
#include "remoting/protocol/session_config.h"
namespace remoting {
scoped_ptr<AudioDecoder> AudioDecoder::CreateAudioDecoder(
const protocol::SessionConfig& config) {
const protocol::ChannelConfig& audio_config = config.audio_config();
if (audio_config.codec == protocol::ChannelConfig::CODEC_VERBATIM) {
return scoped_ptr<AudioDecoder>(new AudioDecoderVerbatim());
}
NOTIMPLEMENTED();
return scoped_ptr<AudioDecoder>(NULL);
}
} // namespace remoting
// 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.
#ifndef REMOTING_CODEC_AUDIO_DECODER_H_
#define REMOTING_CODEC_AUDIO_DECODER_H_
#include "base/memory/scoped_ptr.h"
namespace remoting {
namespace protocol {
class SessionConfig;
} // namespace protocol
class AudioPacket;
class AudioDecoder {
public:
static scoped_ptr<AudioDecoder> CreateAudioDecoder(
const protocol::SessionConfig& config);
virtual ~AudioDecoder() {}
virtual scoped_ptr<AudioPacket> Decode(scoped_ptr<AudioPacket> packet) = 0;
};
} // namespace remoting
#endif // REMOTING_CODEC_AUDIO_DECODER_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/codec/audio_decoder_verbatim.h"
#include "base/logging.h"
#include "remoting/proto/audio.pb.h"
namespace remoting {
AudioDecoderVerbatim::AudioDecoderVerbatim() {
}
AudioDecoderVerbatim::~AudioDecoderVerbatim() {
}
scoped_ptr<AudioPacket> AudioDecoderVerbatim::Decode(
scoped_ptr<AudioPacket> packet) {
DCHECK_EQ(AudioPacket::ENCODING_RAW, packet->encoding());
return packet.Pass();
}
} // namespace remoting
// 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.
#ifndef REMOTING_CODEC_AUDIO_DECODER_VERBATIM_H_
#define REMOTING_CODEC_AUDIO_DECODER_VERBATIM_H_
#include "remoting/codec/audio_decoder.h"
#include "base/memory/scoped_ptr.h"
namespace remoting {
class AudioPacket;
// The decoder for raw audio streams.
class AudioDecoderVerbatim : public AudioDecoder {
public:
AudioDecoderVerbatim();
virtual ~AudioDecoderVerbatim();
virtual scoped_ptr<AudioPacket> Decode(
scoped_ptr<AudioPacket> packet) OVERRIDE;
private:
DISALLOW_COPY_AND_ASSIGN(AudioDecoderVerbatim);
};
} // namespace remoting
#endif // REMOTING_CODEC_AUDIO_DECODER_VERBATIM_H_
......@@ -1194,6 +1194,10 @@
'base/util.h',
# TODO(kxing): Seperate the audio and video codec files into a separate
# target.
'codec/audio_decoder.cc',
'codec/audio_decoder.h',
'codec/audio_decoder_verbatim.cc',
'codec/audio_decoder_verbatim.h',
'codec/audio_encoder.h',
'codec/audio_encoder_verbatim.cc',
'codec/audio_encoder_verbatim.h',
......@@ -1401,6 +1405,8 @@
'remoting_protocol',
],
'sources': [
'client/audio_decode_scheduler.cc',
'client/audio_decode_scheduler.h',
'client/audio_player.h',
'client/chromoting_client.cc',
'client/chromoting_client.h',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment