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 // THREAD SAFETY | 5 // THREAD SAFETY |
6 // | 6 // |
7 // AlsaPcmOutputStream object is *not* thread-safe and should only be used | 7 // AlsaPcmOutputStream object is *not* thread-safe and should only be used |
8 // from the audio thread. We DCHECK on this assumption whenever we can. | 8 // from the audio thread. We DCHECK on this assumption whenever we can. |
9 // | 9 // |
10 // SEMANTICS OF Close() | 10 // SEMANTICS OF Close() |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
42 #include "base/message_loop.h" | 42 #include "base/message_loop.h" |
43 #include "base/stl_util.h" | 43 #include "base/stl_util.h" |
44 #include "base/time.h" | 44 #include "base/time.h" |
45 #include "media/audio/audio_util.h" | 45 #include "media/audio/audio_util.h" |
46 #include "media/audio/linux/alsa_util.h" | 46 #include "media/audio/linux/alsa_util.h" |
47 #include "media/audio/linux/alsa_wrapper.h" | 47 #include "media/audio/linux/alsa_wrapper.h" |
48 #include "media/audio/linux/audio_manager_linux.h" | 48 #include "media/audio/linux/audio_manager_linux.h" |
49 #include "media/base/data_buffer.h" | 49 #include "media/base/data_buffer.h" |
50 #include "media/base/seekable_buffer.h" | 50 #include "media/base/seekable_buffer.h" |
51 | 51 |
52 namespace { | 52 namespace { |
Ami GONE FROM CHROMIUM
2012/01/26 03:51:34
media/ code actually goes the other way - preferri
James Hawkins
2012/01/26 03:53:02
Why would we use two different styles in the same
James Hawkins
2012/01/26 04:13:02
Removed namespace and added back static per-prefer
| |
53 | |
53 // Amount of time to wait if we've exhausted the data source. This is to avoid | 54 // Amount of time to wait if we've exhausted the data source. This is to avoid |
54 // busy looping. | 55 // busy looping. |
55 static const uint32 kNoDataSleepMilliseconds = 10; | 56 const uint32 kNoDataSleepMilliseconds = 10; |
56 | 57 |
57 // Mininum interval between OnMoreData() calls. | 58 // Mininum interval between OnMoreData() calls. |
58 const uint32 kMinIntervalBetweenOnMoreDataCallsInMs = 5; | 59 const uint32 kMinIntervalBetweenOnMoreDataCallsInMs = 5; |
59 | 60 |
60 // According to the linux nanosleep manpage, nanosleep on linux can miss the | 61 // According to the linux nanosleep manpage, nanosleep on linux can miss the |
61 // deadline by up to 10ms because the kernel timeslice is 10ms. Give a 2x | 62 // deadline by up to 10ms because the kernel timeslice is 10ms. Give a 2x |
62 // buffer to compensate for the timeslice, and any additional slowdowns. | 63 // buffer to compensate for the timeslice, and any additional slowdowns. |
63 static const uint32 kSleepErrorMilliseconds = 20; | 64 const uint32 kSleepErrorMilliseconds = 20; |
64 | 65 |
65 // Set to 0 during debugging if you want error messages due to underrun | 66 // Set to 0 during debugging if you want error messages due to underrun |
66 // events or other recoverable errors. | 67 // events or other recoverable errors. |
67 #if defined(NDEBUG) | 68 #if defined(NDEBUG) |
68 static const int kPcmRecoverIsSilent = 1; | 69 const int kPcmRecoverIsSilent = 1; |
69 #else | 70 #else |
70 static const int kPcmRecoverIsSilent = 0; | 71 const int kPcmRecoverIsSilent = 0; |
71 #endif | 72 #endif |
72 | 73 |
73 // ALSA is currently limited to 48kHz. | 74 // ALSA is currently limited to 48kHz. |
74 // TODO(fbarchard): Resample audio from higher frequency to 48000. | 75 // TODO(fbarchard): Resample audio from higher frequency to 48000. |
75 static const int kAlsaMaxSampleRate = 48000; | 76 const int kAlsaMaxSampleRate = 48000; |
76 | 77 |
77 // While the "default" device may support multi-channel audio, in Alsa, only | 78 // While the "default" device may support multi-channel audio, in Alsa, only |
78 // the device names surround40, surround41, surround50, etc, have a defined | 79 // the device names surround40, surround41, surround50, etc, have a defined |
79 // channel mapping according to Lennart: | 80 // channel mapping according to Lennart: |
80 // | 81 // |
81 // http://0pointer.de/blog/projects/guide-to-sound-apis.html | 82 // http://0pointer.de/blog/projects/guide-to-sound-apis.html |
82 // | 83 // |
83 // This function makes a best guess at the specific > 2 channel device name | 84 // This function makes a best guess at the specific > 2 channel device name |
84 // based on the number of channels requested. NULL is returned if no device | 85 // based on the number of channels requested. NULL is returned if no device |
85 // can be found to match the channel numbers. In this case, using | 86 // can be found to match the channel numbers. In this case, using |
86 // kDefaultDevice is probably the best bet. | 87 // kDefaultDevice is probably the best bet. |
87 // | 88 // |
88 // A five channel source is assumed to be surround50 instead of surround41 | 89 // A five channel source is assumed to be surround50 instead of surround41 |
89 // (which is also 5 channels). | 90 // (which is also 5 channels). |
90 // | 91 // |
91 // TODO(ajwong): The source data should have enough info to tell us if we want | 92 // TODO(ajwong): The source data should have enough info to tell us if we want |
92 // surround41 versus surround51, etc., instead of needing us to guess base don | 93 // surround41 versus surround51, etc., instead of needing us to guess base don |
93 // channel number. Fix API to pass that data down. | 94 // channel number. Fix API to pass that data down. |
94 static const char* GuessSpecificDeviceName(uint32 channels) { | 95 const char* GuessSpecificDeviceName(uint32 channels) { |
95 switch (channels) { | 96 switch (channels) { |
96 case 8: | 97 case 8: |
97 return "surround71"; | 98 return "surround71"; |
98 | 99 |
99 case 7: | 100 case 7: |
100 return "surround70"; | 101 return "surround70"; |
101 | 102 |
102 case 6: | 103 case 6: |
103 return "surround51"; | 104 return "surround51"; |
104 | 105 |
105 case 5: | 106 case 5: |
106 return "surround50"; | 107 return "surround50"; |
107 | 108 |
108 case 4: | 109 case 4: |
109 return "surround40"; | 110 return "surround40"; |
110 | 111 |
111 default: | 112 default: |
112 return NULL; | 113 return NULL; |
113 } | 114 } |
114 } | 115 } |
115 | 116 |
116 // Reorder PCM from AAC layout to Alsa layout. | 117 // Reorder PCM from AAC layout to Alsa layout. |
117 // TODO(fbarchard): Switch layout when ffmpeg is updated. | 118 // TODO(fbarchard): Switch layout when ffmpeg is updated. |
118 template<class Format> | 119 template<class Format> |
119 static void Swizzle50Layout(Format* b, uint32 filled) { | 120 void Swizzle50Layout(Format* b, uint32 filled) { |
120 static const uint32 kNumSurroundChannels = 5; | 121 static const uint32 kNumSurroundChannels = 5; |
121 Format aac[kNumSurroundChannels]; | 122 Format aac[kNumSurroundChannels]; |
122 for (uint32 i = 0; i < filled; i += sizeof(aac), b += kNumSurroundChannels) { | 123 for (uint32 i = 0; i < filled; i += sizeof(aac), b += kNumSurroundChannels) { |
123 memcpy(aac, b, sizeof(aac)); | 124 memcpy(aac, b, sizeof(aac)); |
124 b[0] = aac[1]; // L | 125 b[0] = aac[1]; // L |
125 b[1] = aac[2]; // R | 126 b[1] = aac[2]; // R |
126 b[2] = aac[3]; // Ls | 127 b[2] = aac[3]; // Ls |
127 b[3] = aac[4]; // Rs | 128 b[3] = aac[4]; // Rs |
128 b[4] = aac[0]; // C | 129 b[4] = aac[0]; // C |
129 } | 130 } |
130 } | 131 } |
131 | 132 |
132 template<class Format> | 133 template<class Format> |
133 static void Swizzle51Layout(Format* b, uint32 filled) { | 134 void Swizzle51Layout(Format* b, uint32 filled) { |
134 static const uint32 kNumSurroundChannels = 6; | 135 static const uint32 kNumSurroundChannels = 6; |
135 Format aac[kNumSurroundChannels]; | 136 Format aac[kNumSurroundChannels]; |
136 for (uint32 i = 0; i < filled; i += sizeof(aac), b += kNumSurroundChannels) { | 137 for (uint32 i = 0; i < filled; i += sizeof(aac), b += kNumSurroundChannels) { |
137 memcpy(aac, b, sizeof(aac)); | 138 memcpy(aac, b, sizeof(aac)); |
138 b[0] = aac[1]; // L | 139 b[0] = aac[1]; // L |
139 b[1] = aac[2]; // R | 140 b[1] = aac[2]; // R |
140 b[2] = aac[3]; // Ls | 141 b[2] = aac[3]; // Ls |
141 b[3] = aac[4]; // Rs | 142 b[3] = aac[4]; // Rs |
142 b[4] = aac[0]; // C | 143 b[4] = aac[0]; // C |
143 b[5] = aac[5]; // LFE | 144 b[5] = aac[5]; // LFE |
144 } | 145 } |
145 } | 146 } |
146 } // end namespace | 147 |
148 } // namespace | |
147 | 149 |
148 std::ostream& operator<<(std::ostream& os, | 150 std::ostream& operator<<(std::ostream& os, |
149 AlsaPcmOutputStream::InternalState state) { | 151 AlsaPcmOutputStream::InternalState state) { |
150 switch (state) { | 152 switch (state) { |
151 case AlsaPcmOutputStream::kInError: | 153 case AlsaPcmOutputStream::kInError: |
152 os << "kInError"; | 154 os << "kInError"; |
153 break; | 155 break; |
154 case AlsaPcmOutputStream::kCreated: | 156 case AlsaPcmOutputStream::kCreated: |
155 os << "kCreated"; | 157 os << "kCreated"; |
156 break; | 158 break; |
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
839 if (source_callback_) | 841 if (source_callback_) |
840 source_callback_->OnError(this, code); | 842 source_callback_->OnError(this, code); |
841 } | 843 } |
842 | 844 |
843 // Changes the AudioSourceCallback to proxy calls to. Pass in NULL to | 845 // Changes the AudioSourceCallback to proxy calls to. Pass in NULL to |
844 // release ownership of the currently registered callback. | 846 // release ownership of the currently registered callback. |
845 void AlsaPcmOutputStream::set_source_callback(AudioSourceCallback* callback) { | 847 void AlsaPcmOutputStream::set_source_callback(AudioSourceCallback* callback) { |
846 DCHECK(manager_->GetMessageLoop()->BelongsToCurrentThread()); | 848 DCHECK(manager_->GetMessageLoop()->BelongsToCurrentThread()); |
847 source_callback_ = callback; | 849 source_callback_ = callback; |
848 } | 850 } |
OLD | NEW |