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/client/audio_decode_scheduler.h"
8 #include "base/location.h"
9 #include "base/single_thread_task_runner.h"
10 #include "remoting/client/audio_player.h"
11 #include "remoting/codec/audio_decoder.h"
12 #include "remoting/proto/audio.pb.h"
16 class AudioDecodeScheduler::Core
: public base::RefCountedThreadSafe
<Core
> {
18 Core(scoped_refptr
<base::SingleThreadTaskRunner
> main_task_runner
,
19 scoped_refptr
<base::SingleThreadTaskRunner
> audio_decode_task_runner
,
20 scoped_ptr
<AudioPlayer
> audio_player
);
22 void Initialize(const protocol::SessionConfig
& config
);
23 void ProcessAudioPacket(scoped_ptr
<AudioPacket
> packet
,
24 const base::Closure
& done
);
26 // Called by AudioDecodeScheduler when it is destroyed.
30 friend class base::RefCountedThreadSafe
<Core
>;
34 // Called on the audio decoder thread.
35 void DecodePacket(scoped_ptr
<AudioPacket
> packet
, const base::Closure
& done
);
37 // Called on the main thread.
38 void ProcessDecodedPacket(scoped_ptr
<AudioPacket
> packet
,
39 const base::Closure
& done
);
41 scoped_refptr
<base::SingleThreadTaskRunner
> main_task_runner_
;
42 scoped_refptr
<base::SingleThreadTaskRunner
> audio_decode_task_runner_
;
43 scoped_ptr
<AudioDecoder
> decoder_
;
44 scoped_ptr
<AudioPlayer
> audio_player_
;
46 DISALLOW_COPY_AND_ASSIGN(Core
);
49 AudioDecodeScheduler::Core::Core(
50 scoped_refptr
<base::SingleThreadTaskRunner
> main_task_runner
,
51 scoped_refptr
<base::SingleThreadTaskRunner
> audio_decode_task_runner
,
52 scoped_ptr
<AudioPlayer
> audio_player
)
53 : main_task_runner_(main_task_runner
),
54 audio_decode_task_runner_(audio_decode_task_runner
),
55 audio_player_(audio_player
.Pass()) {
58 AudioDecodeScheduler::Core::~Core() {
61 void AudioDecodeScheduler::Core::Initialize(
62 const protocol::SessionConfig
& config
) {
63 DCHECK(main_task_runner_
->BelongsToCurrentThread());
64 decoder_
.reset(AudioDecoder::CreateAudioDecoder(config
).release());
67 void AudioDecodeScheduler::Core::ProcessAudioPacket(
68 scoped_ptr
<AudioPacket
> packet
,
69 const base::Closure
& done
) {
70 DCHECK(main_task_runner_
->BelongsToCurrentThread());
71 audio_decode_task_runner_
->PostTask(FROM_HERE
, base::Bind(
72 &AudioDecodeScheduler::Core::DecodePacket
, this,
73 base::Passed(&packet
), done
));
76 void AudioDecodeScheduler::Core::Detach() {
77 DCHECK(main_task_runner_
->BelongsToCurrentThread());
78 audio_player_
.reset();
81 void AudioDecodeScheduler::Core::DecodePacket(
82 scoped_ptr
<AudioPacket
> packet
,
83 const base::Closure
& done
) {
84 DCHECK(audio_decode_task_runner_
->BelongsToCurrentThread());
85 scoped_ptr
<AudioPacket
> decoded_packet
= decoder_
->Decode(packet
.Pass());
87 main_task_runner_
->PostTask(FROM_HERE
, base::Bind(
88 &AudioDecodeScheduler::Core::ProcessDecodedPacket
, this,
89 base::Passed(&decoded_packet
), done
));
92 void AudioDecodeScheduler::Core::ProcessDecodedPacket(
93 scoped_ptr
<AudioPacket
> packet
,
94 const base::Closure
& done
) {
95 DCHECK(main_task_runner_
->BelongsToCurrentThread());
96 // Only process |packet| if it is non-null.
97 if (packet
.get() && audio_player_
.get())
98 audio_player_
->ProcessAudioPacket(packet
.Pass());
102 AudioDecodeScheduler::AudioDecodeScheduler(
103 scoped_refptr
<base::SingleThreadTaskRunner
> main_task_runner
,
104 scoped_refptr
<base::SingleThreadTaskRunner
> audio_decode_task_runner
,
105 scoped_ptr
<AudioPlayer
> audio_player
)
106 : core_(new Core(main_task_runner
, audio_decode_task_runner
,
107 audio_player
.Pass())) {
110 AudioDecodeScheduler::~AudioDecodeScheduler() {
114 void AudioDecodeScheduler::Initialize(const protocol::SessionConfig
& config
) {
115 core_
->Initialize(config
);
118 void AudioDecodeScheduler::ProcessAudioPacket(scoped_ptr
<AudioPacket
> packet
,
119 const base::Closure
& done
) {
120 core_
->ProcessAudioPacket(packet
.Pass(), done
);
123 } // namespace remoting