Home | History | Annotate | Download | only in host
      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.
      4 
      5 #include "remoting/host/audio_scheduler.h"
      6 
      7 #include "base/bind.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"
     15 
     16 namespace remoting {
     17 
     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),
     29       network_stopped_(false),
     30       enabled_(true) {
     31   DCHECK(network_task_runner_->BelongsToCurrentThread());
     32   DCHECK(audio_capturer_);
     33   DCHECK(audio_encoder_);
     34   DCHECK(audio_stub_);
     35 }
     36 
     37 void AudioScheduler::Start() {
     38   DCHECK(network_task_runner_->BelongsToCurrentThread());
     39 
     40   audio_task_runner_->PostTask(
     41       FROM_HERE, base::Bind(&AudioScheduler::StartOnAudioThread, this));
     42 }
     43 
     44 void AudioScheduler::Stop() {
     45   DCHECK(network_task_runner_->BelongsToCurrentThread());
     46   DCHECK(audio_stub_);
     47 
     48   // Clear |audio_stub_| to prevent audio packets being delivered to the client.
     49   audio_stub_ = NULL;
     50 
     51   audio_task_runner_->PostTask(
     52       FROM_HERE,
     53       base::Bind(&AudioScheduler::StopOnAudioThread, this));
     54 }
     55 
     56 AudioScheduler::~AudioScheduler() {
     57 }
     58 
     59 void AudioScheduler::StartOnAudioThread() {
     60   DCHECK(audio_task_runner_->BelongsToCurrentThread());
     61 
     62   // TODO(kxing): Do something with the return value.
     63   audio_capturer_->Start(
     64       base::Bind(&AudioScheduler::EncodeAudioPacket, this));
     65 }
     66 
     67 void AudioScheduler::StopOnAudioThread() {
     68   DCHECK(audio_task_runner_->BelongsToCurrentThread());
     69   audio_capturer_->Stop();
     70 }
     71 
     72 void AudioScheduler::Pause(bool pause) {
     73   if (!audio_task_runner_->BelongsToCurrentThread()) {
     74     audio_task_runner_->PostTask(
     75         FROM_HERE, base::Bind(&AudioScheduler::Pause, this, pause));
     76     return;
     77   }
     78 
     79   enabled_ = !pause;
     80 }
     81 
     82 void AudioScheduler::EncodeAudioPacket(scoped_ptr<AudioPacket> packet) {
     83   DCHECK(audio_task_runner_->BelongsToCurrentThread());
     84   DCHECK(packet.get());
     85 
     86   if (!enabled_)
     87     return;
     88 
     89   scoped_ptr<AudioPacket> encoded_packet =
     90       audio_encoder_->Encode(packet.Pass());
     91 
     92   // The audio encoder returns a NULL audio packet if there's no audio to send.
     93   if (encoded_packet.get()) {
     94     network_task_runner_->PostTask(
     95         FROM_HERE, base::Bind(&AudioScheduler::SendAudioPacket,
     96                               this, base::Passed(&encoded_packet)));
     97   }
     98 }
     99 
    100 void AudioScheduler::SendAudioPacket(scoped_ptr<AudioPacket> packet) {
    101   DCHECK(network_task_runner_->BelongsToCurrentThread());
    102   DCHECK(packet.get());
    103 
    104   if (!audio_stub_)
    105     return;
    106 
    107   audio_stub_->ProcessAudioPacket(packet.Pass(), base::Closure());
    108 }
    109 
    110 }  // namespace remoting
    111