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 "remoting/client/plugin/pepper_audio_player.h" | 5 #include "remoting/client/plugin/pepper_audio_player.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
10 #include "remoting/proto/audio.pb.h" | |
11 | 10 |
12 namespace { | 11 namespace { |
13 // Constants used to create an audio configuration resource. | 12 // Constants used to create an audio configuration resource. |
14 // The sample count we will request from the browser. | 13 // The sample count we will request from the browser. |
15 const uint32_t kSampleFrameCount = 4096u; | 14 const uint32_t kSampleFrameCount = 4096u; |
16 // The number of channels in the audio stream (only supporting stereo audio | 15 // The number of channels in the audio stream (only supporting stereo audio |
17 // for now). | 16 // for now). |
18 const uint32_t kChannels = 2u; | 17 const uint32_t kChannels = 2u; |
19 const int kSampleSizeBytes = 2; | 18 const int kSampleSizeBytes = 2; |
19 | |
20 PP_AudioSampleRate ConvertToPepperSampleRate( | |
21 remoting::AudioPacket::SamplingRate sampling_rate) { | |
22 switch (sampling_rate) { | |
23 case remoting::AudioPacket::SAMPLING_RATE_44100: | |
24 return PP_AUDIOSAMPLERATE_44100; | |
25 case remoting::AudioPacket::SAMPLING_RATE_48000: | |
26 return PP_AUDIOSAMPLERATE_48000; | |
27 default: | |
28 NOTREACHED(); | |
29 } | |
30 return PP_AUDIOSAMPLERATE_NONE; | |
31 } | |
32 | |
20 } // namespace | 33 } // namespace |
21 | 34 |
22 namespace remoting { | 35 namespace remoting { |
23 | 36 |
24 bool PepperAudioPlayer::IsRunning() const { | 37 PepperAudioPlayer::PepperAudioPlayer(pp::Instance* instance) |
25 return running_; | 38 : instance_(instance), |
39 sampling_rate_(AudioPacket::SAMPLING_RATE_INVALID), | |
40 samples_per_frame_(kSampleFrameCount), | |
41 bytes_consumed_(0), | |
42 start_failed_(false) { | |
26 } | 43 } |
27 | 44 |
28 PepperAudioPlayer::PepperAudioPlayer(pp::Instance* instance) | 45 PepperAudioPlayer::~PepperAudioPlayer() {} |
29 : samples_per_frame_(kSampleFrameCount), | 46 |
30 bytes_consumed_(0), | 47 bool PepperAudioPlayer::ResetAudioPlayer( |
31 running_(false) { | 48 AudioPacket::SamplingRate sampling_rate) { |
Wez
2012/08/07 20:09:49
nit: It seems cleaner to clear any queued packets
| |
49 sampling_rate_ = sampling_rate; | |
50 PP_AudioSampleRate sample_rate = | |
51 ConvertToPepperSampleRate(sampling_rate); | |
52 | |
32 // Ask the browser/device for an appropriate sample frame count size. | 53 // Ask the browser/device for an appropriate sample frame count size. |
33 samples_per_frame_ = | 54 samples_per_frame_ = |
34 pp::AudioConfig::RecommendSampleFrameCount(instance, | 55 pp::AudioConfig::RecommendSampleFrameCount(instance_, |
35 PP_AUDIOSAMPLERATE_44100, | 56 sample_rate, |
36 kSampleFrameCount); | 57 kSampleFrameCount); |
37 | 58 |
38 // Create an audio configuration resource. | 59 // Create an audio configuration resource. |
39 pp::AudioConfig audio_config = pp::AudioConfig(instance, | 60 pp::AudioConfig audio_config = pp::AudioConfig(instance_, |
40 PP_AUDIOSAMPLERATE_44100, | 61 sample_rate, |
41 samples_per_frame_); | 62 samples_per_frame_); |
42 | 63 |
43 // Create an audio resource. | 64 // Create an audio resource. |
44 audio_ = pp::Audio(instance, audio_config, PepperAudioPlayerCallback, this); | 65 audio_ = pp::Audio(instance_, audio_config, PepperAudioPlayerCallback, this); |
45 } | |
46 | 66 |
47 PepperAudioPlayer::~PepperAudioPlayer() { } | 67 // Immediately start the player. |
48 | 68 bool success = audio_.StartPlayback(); |
49 bool PepperAudioPlayer::Start() { | 69 if (!success) |
50 running_ = audio_.StartPlayback(); | 70 LOG(ERROR) << "Failed to start Pepper audio player"; |
Wez
2012/08/07 20:09:49
nit: Why log this here, rather than letting the ca
| |
51 return running_; | 71 return success; |
52 } | 72 } |
53 | 73 |
54 void PepperAudioPlayer::ProcessAudioPacket(scoped_ptr<AudioPacket> packet) { | 74 void PepperAudioPlayer::ProcessAudioPacket(scoped_ptr<AudioPacket> packet) { |
55 // TODO(kxing): Limit the size of the queue so that latency doesn't grow | 75 // TODO(kxing): Limit the size of the queue so that latency doesn't grow |
56 // too large. | 76 // too large. |
57 if (packet->data().size() % (kChannels * kSampleSizeBytes) != 0) { | 77 if (packet->data().size() % (kChannels * kSampleSizeBytes) != 0) { |
58 LOG(WARNING) << "Received corrupted packet."; | 78 LOG(WARNING) << "Received corrupted packet."; |
59 return; | 79 return; |
60 } | 80 } |
61 base::AutoLock auto_lock(lock_); | 81 base::AutoLock auto_lock(lock_); |
62 | 82 |
83 // No-op if the Pepper player won't start. | |
84 if (start_failed_) { | |
85 return; | |
86 } | |
87 | |
88 // Start the Pepper audio player if this is the first packet. | |
Wez
2012/08/07 20:09:49
nit: If you perform this check before testing star
| |
89 if (sampling_rate_ != packet->sampling_rate()) { | |
Wez
2012/08/07 20:09:49
nit: You could move this check into ResetAudioPlay
| |
90 // Drop all packets currently in the queue, since they are sampled at the | |
91 // wrong rate. | |
92 STLDeleteElements(&queued_packets_); | |
93 | |
94 bool success = ResetAudioPlayer(packet->sampling_rate()); | |
95 if (!success) { | |
96 start_failed_ = true; | |
97 return; | |
98 } | |
99 } | |
100 | |
63 queued_packets_.push_back(packet.release()); | 101 queued_packets_.push_back(packet.release()); |
64 } | 102 } |
65 | 103 |
66 // static | 104 // static |
67 void PepperAudioPlayer::PepperAudioPlayerCallback(void* samples, | 105 void PepperAudioPlayer::PepperAudioPlayerCallback(void* samples, |
68 uint32_t buffer_size, | 106 uint32_t buffer_size, |
69 void* data) { | 107 void* data) { |
70 PepperAudioPlayer* audio_player = static_cast<PepperAudioPlayer*>(data); | 108 PepperAudioPlayer* audio_player = static_cast<PepperAudioPlayer*>(data); |
71 audio_player->FillWithSamples(samples, buffer_size); | 109 audio_player->FillWithSamples(samples, buffer_size); |
72 } | 110 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
104 bytes_needed - bytes_extracted); | 142 bytes_needed - bytes_extracted); |
105 memcpy(next_sample, packet_data.data() + bytes_consumed_, bytes_to_copy); | 143 memcpy(next_sample, packet_data.data() + bytes_consumed_, bytes_to_copy); |
106 | 144 |
107 next_sample += bytes_to_copy; | 145 next_sample += bytes_to_copy; |
108 bytes_consumed_ += bytes_to_copy; | 146 bytes_consumed_ += bytes_to_copy; |
109 bytes_extracted += bytes_to_copy; | 147 bytes_extracted += bytes_to_copy; |
110 } | 148 } |
111 } | 149 } |
112 | 150 |
113 } // namespace remoting | 151 } // namespace remoting |
OLD | NEW |