1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "remoting/host/audio_scheduler.h"
8 #include "base/location.h"
9 #include "base/logging.h"
10 #include "base/single_thread_task_runner.h"
11 #include "remoting/codec/audio_encoder.h"
12 #include "remoting/host/audio_capturer.h"
13 #include "remoting/proto/audio.pb.h"
14 #include "remoting/protocol/audio_stub.h"
18 AudioScheduler::AudioScheduler(
19 scoped_refptr
<base::SingleThreadTaskRunner
> audio_task_runner
,
20 scoped_refptr
<base::SingleThreadTaskRunner
> network_task_runner
,
21 scoped_ptr
<AudioCapturer
> audio_capturer
,
22 scoped_ptr
<AudioEncoder
> audio_encoder
,
23 protocol::AudioStub
* audio_stub
)
24 : audio_task_runner_(audio_task_runner
),
25 network_task_runner_(network_task_runner
),
26 audio_capturer_(audio_capturer
.Pass()),
27 audio_encoder_(audio_encoder
.Pass()),
28 audio_stub_(audio_stub
),
30 DCHECK(network_task_runner_
->BelongsToCurrentThread());
31 DCHECK(audio_capturer_
);
32 DCHECK(audio_encoder_
);
36 void AudioScheduler::Start() {
37 DCHECK(network_task_runner_
->BelongsToCurrentThread());
39 audio_task_runner_
->PostTask(
40 FROM_HERE
, base::Bind(&AudioScheduler::StartOnAudioThread
, this));
43 void AudioScheduler::Stop() {
44 DCHECK(network_task_runner_
->BelongsToCurrentThread());
47 // Clear |audio_stub_| to prevent audio packets being delivered to the client.
48 audio_stub_
= nullptr;
50 audio_task_runner_
->PostTask(
52 base::Bind(&AudioScheduler::StopOnAudioThread
, this));
55 AudioScheduler::~AudioScheduler() {
58 void AudioScheduler::StartOnAudioThread() {
59 DCHECK(audio_task_runner_
->BelongsToCurrentThread());
61 // TODO(kxing): Do something with the return value.
62 audio_capturer_
->Start(
63 base::Bind(&AudioScheduler::EncodeAudioPacket
, this));
66 void AudioScheduler::StopOnAudioThread() {
67 DCHECK(audio_task_runner_
->BelongsToCurrentThread());
68 audio_capturer_
->Stop();
71 void AudioScheduler::Pause(bool pause
) {
72 if (!audio_task_runner_
->BelongsToCurrentThread()) {
73 audio_task_runner_
->PostTask(
74 FROM_HERE
, base::Bind(&AudioScheduler::Pause
, this, pause
));
81 void AudioScheduler::EncodeAudioPacket(scoped_ptr
<AudioPacket
> packet
) {
82 DCHECK(audio_task_runner_
->BelongsToCurrentThread());
88 scoped_ptr
<AudioPacket
> encoded_packet
=
89 audio_encoder_
->Encode(packet
.Pass());
91 // The audio encoder returns a null audio packet if there's no audio to send.
92 if (encoded_packet
.get()) {
93 network_task_runner_
->PostTask(
94 FROM_HERE
, base::Bind(&AudioScheduler::SendAudioPacket
,
95 this, base::Passed(&encoded_packet
)));
99 void AudioScheduler::SendAudioPacket(scoped_ptr
<AudioPacket
> packet
) {
100 DCHECK(network_task_runner_
->BelongsToCurrentThread());
101 DCHECK(packet
.get());
106 audio_stub_
->ProcessAudioPacket(packet
.Pass(), base::Closure());
109 } // namespace remoting