| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <windows.h> | 5 #include <windows.h> |
| 6 #include <audioclient.h> | 6 #include <audioclient.h> |
| 7 #include <avrt.h> | 7 #include <avrt.h> |
| 8 #include <mmdeviceapi.h> | 8 #include <mmdeviceapi.h> |
| 9 #include <mmreg.h> | 9 #include <mmreg.h> |
| 10 #include <mmsystem.h> | 10 #include <mmsystem.h> |
| 11 #include <string> |
| 11 | 12 |
| 12 #include "base/basictypes.h" | 13 #include "base/basictypes.h" |
| 13 #include "base/logging.h" | 14 #include "base/logging.h" |
| 14 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
| 15 #include "base/message_loop.h" | 16 #include "base/message_loop.h" |
| 16 #include "base/timer.h" | 17 #include "base/timer.h" |
| 17 #include "base/win/scoped_co_mem.h" | 18 #include "base/win/scoped_co_mem.h" |
| 18 #include "base/win/scoped_com_initializer.h" | 19 #include "base/win/scoped_com_initializer.h" |
| 19 #include "base/win/scoped_comptr.h" | 20 #include "base/win/scoped_comptr.h" |
| 21 #include "remoting/base/audio_capture_data.h" |
| 20 #include "remoting/host/audio_capturer.h" | 22 #include "remoting/host/audio_capturer.h" |
| 21 #include "remoting/proto/audio.pb.h" | 23 #include "remoting/proto/audio.pb.h" |
| 22 | 24 |
| 23 namespace { | 25 namespace { |
| 24 const int kChannels = 2; | 26 const int kChannels = 2; |
| 25 const int kBitsPerSample = 16; | 27 const int kBitsPerSample = 16; |
| 26 const int kBitsPerByte = 8; | 28 const int kBitsPerByte = 8; |
| 27 // Conversion factor from 100ns to 1ms. | 29 // Conversion factor from 100ns to 1ms. |
| 28 const int kHnsToMs = 10000; | 30 const int kHnsToMs = 10000; |
| 29 } // namespace | 31 } // namespace |
| 30 | 32 |
| 31 namespace remoting { | 33 namespace remoting { |
| 32 | 34 |
| 33 class AudioCapturerWin : public AudioCapturer { | 35 class AudioCapturerWin : public AudioCapturer { |
| 34 public: | 36 public: |
| 35 AudioCapturerWin(); | 37 AudioCapturerWin(); |
| 36 virtual ~AudioCapturerWin(); | 38 virtual ~AudioCapturerWin(); |
| 37 | 39 |
| 38 // AudioCapturer interface. | 40 // AudioCapturer interface. |
| 39 virtual bool Start(const PacketCapturedCallback& callback) OVERRIDE; | 41 virtual bool Start(const AudioSamplesCapturedCallback& callback) OVERRIDE; |
| 40 virtual void Stop() OVERRIDE; | 42 virtual void Stop() OVERRIDE; |
| 41 virtual bool IsRunning() OVERRIDE; | 43 virtual bool IsRunning() OVERRIDE; |
| 42 | 44 |
| 43 private: | 45 private: |
| 44 // Receives all packets from the audio capture endpoint buffer and pushes them | 46 // Receives all packets from the audio capture endpoint buffer and pushes them |
| 45 // to the network. | 47 // to the network. |
| 46 void DoCapture(); | 48 void DoCapture(); |
| 47 | 49 |
| 48 PacketCapturedCallback callback_; | 50 AudioSamplesCapturedCallback callback_; |
| 49 | 51 |
| 50 AudioPacket::SamplingRate sampling_rate_; | 52 AudioPacket::SamplingRate sampling_rate_; |
| 51 | 53 |
| 52 scoped_ptr<base::RepeatingTimer<AudioCapturerWin> > capture_timer_; | 54 scoped_ptr<base::RepeatingTimer<AudioCapturerWin> > capture_timer_; |
| 53 base::TimeDelta audio_device_period_; | 55 base::TimeDelta audio_device_period_; |
| 54 | 56 |
| 55 base::win::ScopedCoMem<WAVEFORMATEX> wave_format_ex_; | 57 base::win::ScopedCoMem<WAVEFORMATEX> wave_format_ex_; |
| 56 base::win::ScopedComPtr<IAudioCaptureClient> audio_capture_client_; | 58 base::win::ScopedComPtr<IAudioCaptureClient> audio_capture_client_; |
| 57 base::win::ScopedComPtr<IAudioClient> audio_client_; | 59 base::win::ScopedComPtr<IAudioClient> audio_client_; |
| 58 base::win::ScopedComPtr<IMMDevice> mm_device_; | 60 base::win::ScopedComPtr<IMMDevice> mm_device_; |
| 59 scoped_ptr<base::win::ScopedCOMInitializer> com_initializer_; | 61 scoped_ptr<base::win::ScopedCOMInitializer> com_initializer_; |
| 60 | 62 |
| 61 base::ThreadChecker thread_checker_; | 63 base::ThreadChecker thread_checker_; |
| 62 | 64 |
| 63 DISALLOW_COPY_AND_ASSIGN(AudioCapturerWin); | 65 DISALLOW_COPY_AND_ASSIGN(AudioCapturerWin); |
| 64 }; | 66 }; |
| 65 | 67 |
| 66 AudioCapturerWin::AudioCapturerWin() | 68 AudioCapturerWin::AudioCapturerWin() |
| 67 : sampling_rate_(AudioPacket::SAMPLING_RATE_INVALID) { | 69 : sampling_rate_(AudioPacket::SAMPLING_RATE_INVALID) { |
| 68 thread_checker_.DetachFromThread(); | 70 thread_checker_.DetachFromThread(); |
| 69 } | 71 } |
| 70 | 72 |
| 71 AudioCapturerWin::~AudioCapturerWin() { | 73 AudioCapturerWin::~AudioCapturerWin() { |
| 72 } | 74 } |
| 73 | 75 |
| 74 bool AudioCapturerWin::Start(const PacketCapturedCallback& callback) { | 76 bool AudioCapturerWin::Start(const AudioSamplesCapturedCallback& callback) { |
| 75 DCHECK(!audio_capture_client_.get()); | 77 DCHECK(!audio_capture_client_.get()); |
| 76 DCHECK(!audio_client_.get()); | 78 DCHECK(!audio_client_.get()); |
| 77 DCHECK(!mm_device_.get()); | 79 DCHECK(!mm_device_.get()); |
| 78 DCHECK(static_cast<PWAVEFORMATEX>(wave_format_ex_) == NULL); | 80 DCHECK(static_cast<PWAVEFORMATEX>(wave_format_ex_) == NULL); |
| 79 DCHECK(thread_checker_.CalledOnValidThread()); | 81 DCHECK(thread_checker_.CalledOnValidThread()); |
| 80 | 82 |
| 81 callback_ = callback; | 83 callback_ = callback; |
| 82 | 84 |
| 83 // Initialize the capture timer. | 85 // Initialize the capture timer. |
| 84 capture_timer_.reset(new base::RepeatingTimer<AudioCapturerWin>()); | 86 capture_timer_.reset(new base::RepeatingTimer<AudioCapturerWin>()); |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 BYTE* data; | 259 BYTE* data; |
| 258 UINT32 frames; | 260 UINT32 frames; |
| 259 DWORD flags; | 261 DWORD flags; |
| 260 hr = audio_capture_client_->GetBuffer( | 262 hr = audio_capture_client_->GetBuffer( |
| 261 &data, &frames, &flags, NULL, NULL); | 263 &data, &frames, &flags, NULL, NULL); |
| 262 if (FAILED(hr)) { | 264 if (FAILED(hr)) { |
| 263 LOG(ERROR) << "Failed to GetBuffer. Error " << hr; | 265 LOG(ERROR) << "Failed to GetBuffer. Error " << hr; |
| 264 return; | 266 return; |
| 265 } | 267 } |
| 266 | 268 |
| 267 scoped_ptr<AudioPacket> packet = scoped_ptr<AudioPacket>(new AudioPacket()); | 269 scoped_ptr<AudioCaptureData> capture_data = |
| 268 packet->set_data(data, frames * wave_format_ex_->nBlockAlign); | 270 scoped_ptr<AudioCaptureData>(new AudioCaptureData()); |
| 269 packet->set_sampling_rate(sampling_rate_); | 271 capture_data->set_data(std::string( |
| 272 reinterpret_cast<const char*>(data), |
| 273 frames * wave_format_ex_->nBlockAlign)); |
| 274 capture_data->set_sampling_rate(sampling_rate_); |
| 270 | 275 |
| 271 callback_.Run(packet.Pass()); | 276 callback_.Run(capture_data.Pass()); |
| 272 | 277 |
| 273 hr = audio_capture_client_->ReleaseBuffer(frames); | 278 hr = audio_capture_client_->ReleaseBuffer(frames); |
| 274 if (FAILED(hr)) { | 279 if (FAILED(hr)) { |
| 275 LOG(ERROR) << "Failed to ReleaseBuffer. Error " << hr; | 280 LOG(ERROR) << "Failed to ReleaseBuffer. Error " << hr; |
| 276 return; | 281 return; |
| 277 } | 282 } |
| 278 } | 283 } |
| 279 } | 284 } |
| 280 | 285 |
| 281 scoped_ptr<AudioCapturer> AudioCapturer::Create() { | 286 scoped_ptr<AudioCapturer> AudioCapturer::Create() { |
| 282 return scoped_ptr<AudioCapturer>(new AudioCapturerWin()); | 287 return scoped_ptr<AudioCapturer>(new AudioCapturerWin()); |
| 283 } | 288 } |
| 284 | 289 |
| 285 } // namespace remoting | 290 } // namespace remoting |
| OLD | NEW |