OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 <algorithm> | 5 #include <algorithm> |
6 #include <limits> | 6 #include <limits> |
7 | 7 |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "mojo/services/media/common/cpp/linear_transform.h" | 9 #include "mojo/services/media/common/cpp/linear_transform.h" |
10 #include "services/media/audio/audio_output_manager.h" | 10 #include "services/media/audio/audio_output_manager.h" |
11 #include "services/media/audio/audio_server_impl.h" | 11 #include "services/media/audio/audio_server_impl.h" |
12 #include "services/media/audio/audio_track_impl.h" | 12 #include "services/media/audio/audio_track_impl.h" |
13 #include "services/media/audio/audio_track_to_output_link.h" | 13 #include "services/media/audio/audio_track_to_output_link.h" |
14 | 14 |
15 namespace mojo { | 15 namespace mojo { |
16 namespace media { | 16 namespace media { |
17 namespace audio { | 17 namespace audio { |
18 | 18 |
19 constexpr size_t AudioTrackImpl::PTS_FRACTIONAL_BITS; | 19 constexpr size_t AudioTrackImpl::PTS_FRACTIONAL_BITS; |
20 | 20 |
21 // TODO(johngro): If there is ever a better way to do this type of static-table | 21 // TODO(johngro): If there is ever a better way to do this type of static-table |
22 // initialization using mojom generated structs, we should switch to it. | 22 // initialization using mojom generated structs, we should switch to it. |
23 static const struct { | 23 static const struct { |
24 LpcmSampleFormat sample_format; | 24 AudioSampleFormat sample_format; |
25 uint32_t min_channels; | 25 uint32_t min_channels; |
26 uint32_t max_channels; | 26 uint32_t max_channels; |
27 uint32_t min_frames_per_second; | 27 uint32_t min_frames_per_second; |
28 uint32_t max_frames_per_second; | 28 uint32_t max_frames_per_second; |
29 } kSupportedLpcmTypeSets[] = { | 29 } kSupportedAudioTypeSets[] = { |
30 { | 30 { |
31 .sample_format = LpcmSampleFormat::UNSIGNED_8, | 31 .sample_format = AudioSampleFormat::UNSIGNED_8, |
32 .min_channels = 1, | 32 .min_channels = 1, |
33 .max_channels = 2, | 33 .max_channels = 2, |
34 .min_frames_per_second = 1000, | 34 .min_frames_per_second = 1000, |
35 .max_frames_per_second = 48000, | 35 .max_frames_per_second = 48000, |
36 }, | 36 }, |
37 { | 37 { |
38 .sample_format = LpcmSampleFormat::SIGNED_16, | 38 .sample_format = AudioSampleFormat::SIGNED_16, |
39 .min_channels = 1, | 39 .min_channels = 1, |
40 .max_channels = 2, | 40 .max_channels = 2, |
41 .min_frames_per_second = 1000, | 41 .min_frames_per_second = 1000, |
42 .max_frames_per_second = 48000, | 42 .max_frames_per_second = 48000, |
43 }, | 43 }, |
44 }; | 44 }; |
45 | 45 |
46 AudioTrackImpl::AudioTrackImpl(InterfaceRequest<AudioTrack> iface, | 46 AudioTrackImpl::AudioTrackImpl(InterfaceRequest<AudioTrack> iface, |
47 AudioServerImpl* owner) | 47 AudioServerImpl* owner) |
48 : owner_(owner), | 48 : owner_(owner), |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 // compiled with. | 101 // compiled with. |
102 // | 102 // |
103 // For now, it would be nice to just be able to have a static const tree of | 103 // For now, it would be nice to just be able to have a static const tree of |
104 // capabilities in this translational unit which we could use to construct our | 104 // capabilities in this translational unit which we could use to construct our |
105 // message, but the nature of the structures generated by the C++ bindings | 105 // message, but the nature of the structures generated by the C++ bindings |
106 // make this difficult. For now, we just create a trivial descriptor entierly | 106 // make this difficult. For now, we just create a trivial descriptor entierly |
107 // by hand. | 107 // by hand. |
108 AudioTrackDescriptorPtr desc(AudioTrackDescriptor::New()); | 108 AudioTrackDescriptorPtr desc(AudioTrackDescriptor::New()); |
109 | 109 |
110 desc->supported_media_types = | 110 desc->supported_media_types = |
111 Array<MediaTypeSetPtr>::New(arraysize(kSupportedLpcmTypeSets)); | 111 Array<MediaTypeSetPtr>::New(arraysize(kSupportedAudioTypeSets)); |
112 | 112 |
113 for (size_t i = 0; i < desc->supported_media_types.size(); ++i) { | 113 for (size_t i = 0; i < desc->supported_media_types.size(); ++i) { |
114 const MediaTypeSetPtr& mts = | 114 const MediaTypeSetPtr& mts = |
115 (desc->supported_media_types[i] = MediaTypeSet::New()); | 115 (desc->supported_media_types[i] = MediaTypeSet::New()); |
116 | 116 |
117 mts->scheme = MediaTypeScheme::LPCM; | 117 mts->medium = MediaTypeMedium::AUDIO; |
118 mts->details = MediaTypeSetDetails::New(); | 118 mts->encodings = Array<String>::New(1); |
| 119 mts->details = MediaTypeSetDetails::New(); |
119 | 120 |
120 const auto& s = kSupportedLpcmTypeSets[i]; | 121 mts->encodings[0] = MediaType::kAudioEncodingLpcm; |
121 LpcmMediaTypeSetDetailsPtr lpcm_detail = LpcmMediaTypeSetDetails::New(); | |
122 | 122 |
123 lpcm_detail->sample_format = s.sample_format; | 123 const auto& s = kSupportedAudioTypeSets[i]; |
124 lpcm_detail->min_channels = s.min_channels; | 124 AudioMediaTypeSetDetailsPtr audio_detail = AudioMediaTypeSetDetails::New(); |
125 lpcm_detail->max_channels = s.max_channels; | 125 |
126 lpcm_detail->min_frames_per_second = s.min_frames_per_second; | 126 audio_detail->sample_format = s.sample_format; |
127 lpcm_detail->max_frames_per_second = s.max_frames_per_second; | 127 audio_detail->min_channels = s.min_channels; |
128 mts->details->set_lpcm(lpcm_detail.Pass()); | 128 audio_detail->max_channels = s.max_channels; |
| 129 audio_detail->min_frames_per_second = s.min_frames_per_second; |
| 130 audio_detail->max_frames_per_second = s.max_frames_per_second; |
| 131 mts->details->set_audio(audio_detail.Pass()); |
129 } | 132 } |
130 | 133 |
131 cbk.Run(desc.Pass()); | 134 cbk.Run(desc.Pass()); |
132 } | 135 } |
133 | 136 |
134 void AudioTrackImpl::Configure(AudioTrackConfigurationPtr configuration, | 137 void AudioTrackImpl::Configure(AudioTrackConfigurationPtr configuration, |
135 InterfaceRequest<MediaConsumer> req) { | 138 InterfaceRequest<MediaConsumer> req) { |
136 // Are we already configured? | 139 // Are we already configured? |
137 if (pipe_.IsInitialized()) { | 140 if (pipe_.IsInitialized()) { |
138 LOG(ERROR) << "Attempting to reconfigure a configured audio track."; | 141 LOG(ERROR) << "Attempting to reconfigure a configured audio track."; |
139 Shutdown(); | 142 Shutdown(); |
140 return; | 143 return; |
141 } | 144 } |
142 | 145 |
143 // Check the requested configuration. | 146 // Check the requested configuration. |
144 if ((configuration->media_type->scheme != MediaTypeScheme::LPCM) || | 147 if ((configuration->media_type->medium != MediaTypeMedium::AUDIO) || |
145 (!configuration->media_type->details->is_lpcm())) { | 148 (configuration->media_type->encoding != MediaType::kAudioEncodingLpcm) || |
| 149 (!configuration->media_type->details->is_audio())) { |
146 LOG(ERROR) << "Unsupported configuration requested in " | 150 LOG(ERROR) << "Unsupported configuration requested in " |
147 "AudioTrack::Configure. Media type must be LPCM."; | 151 "AudioTrack::Configure. Media type must be LPCM audio."; |
148 Shutdown(); | 152 Shutdown(); |
149 return; | 153 return; |
150 } | 154 } |
151 | 155 |
152 // Search our supported configuration sets to find one compatible with this | 156 // Search our supported configuration sets to find one compatible with this |
153 // request. | 157 // request. |
154 auto& cfg = configuration->media_type->details->get_lpcm(); | 158 auto& cfg = configuration->media_type->details->get_audio(); |
155 size_t i; | 159 size_t i; |
156 for (i = 0; i < arraysize(kSupportedLpcmTypeSets); ++i) { | 160 for (i = 0; i < arraysize(kSupportedAudioTypeSets); ++i) { |
157 const auto& cfg_set = kSupportedLpcmTypeSets[i]; | 161 const auto& cfg_set = kSupportedAudioTypeSets[i]; |
158 | 162 |
159 if ((cfg->sample_format == cfg_set.sample_format) && | 163 if ((cfg->sample_format == cfg_set.sample_format) && |
160 (cfg->channels >= cfg_set.min_channels) && | 164 (cfg->channels >= cfg_set.min_channels) && |
161 (cfg->channels <= cfg_set.max_channels) && | 165 (cfg->channels <= cfg_set.max_channels) && |
162 (cfg->frames_per_second >= cfg_set.min_frames_per_second) && | 166 (cfg->frames_per_second >= cfg_set.min_frames_per_second) && |
163 (cfg->frames_per_second <= cfg_set.max_frames_per_second)) { | 167 (cfg->frames_per_second <= cfg_set.max_frames_per_second)) { |
164 break; | 168 break; |
165 } | 169 } |
166 } | 170 } |
167 | 171 |
168 if (i >= arraysize(kSupportedLpcmTypeSets)) { | 172 if (i >= arraysize(kSupportedAudioTypeSets)) { |
169 LOG(ERROR) << "Unsupported LPCM configuration requested in " | 173 LOG(ERROR) << "Unsupported LPCM configuration requested in " |
170 "AudioTrack::Configure. " | 174 "AudioTrack::Configure. " |
171 << "(format = " << cfg->sample_format | 175 << "(format = " << cfg->sample_format |
172 << ", channels = " | 176 << ", channels = " |
173 << static_cast<uint32_t>(cfg->channels) | 177 << static_cast<uint32_t>(cfg->channels) |
174 << ", frames_per_second = " << cfg->frames_per_second | 178 << ", frames_per_second = " << cfg->frames_per_second |
175 << ")"; | 179 << ")"; |
176 Shutdown(); | 180 Shutdown(); |
177 return; | 181 return; |
178 } | 182 } |
(...skipping 20 matching lines...) Expand all Loading... |
199 if (!no_loss) { | 203 if (!no_loss) { |
200 LOG(ERROR) << "Invalid (audio frames:media time ticks) ratio (" | 204 LOG(ERROR) << "Invalid (audio frames:media time ticks) ratio (" |
201 << numerator << "/" << denominator << ")"; | 205 << numerator << "/" << denominator << ")"; |
202 Shutdown(); | 206 Shutdown(); |
203 return; | 207 return; |
204 } | 208 } |
205 | 209 |
206 // Figure out how many bytes we need to hold the requested number of nSec of | 210 // Figure out how many bytes we need to hold the requested number of nSec of |
207 // audio. | 211 // audio. |
208 switch (cfg->sample_format) { | 212 switch (cfg->sample_format) { |
209 case LpcmSampleFormat::UNSIGNED_8: | 213 case AudioSampleFormat::UNSIGNED_8: |
210 bytes_per_frame_ = 1; | 214 bytes_per_frame_ = 1; |
211 break; | 215 break; |
212 | 216 |
213 case LpcmSampleFormat::SIGNED_16: | 217 case AudioSampleFormat::SIGNED_16: |
214 bytes_per_frame_ = 2; | 218 bytes_per_frame_ = 2; |
215 break; | 219 break; |
216 | 220 |
217 case LpcmSampleFormat::SIGNED_24_IN_32: | 221 case AudioSampleFormat::SIGNED_24_IN_32: |
218 bytes_per_frame_ = 4; | 222 bytes_per_frame_ = 4; |
219 break; | 223 break; |
220 | 224 |
221 default: | 225 default: |
222 DCHECK(false); | 226 DCHECK(false); |
223 bytes_per_frame_ = 2; | 227 bytes_per_frame_ = 2; |
224 break; | 228 break; |
225 } | 229 } |
226 bytes_per_frame_ *= cfg->channels; | 230 bytes_per_frame_ *= cfg->channels; |
227 | 231 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 DCHECK(output); | 317 DCHECK(output); |
314 output->FlushPendingQueue(); | 318 output->FlushPendingQueue(); |
315 } | 319 } |
316 cbk.Run(); | 320 cbk.Run(); |
317 return true; | 321 return true; |
318 } | 322 } |
319 | 323 |
320 } // namespace audio | 324 } // namespace audio |
321 } // namespace media | 325 } // namespace media |
322 } // namespace mojo | 326 } // namespace mojo |
OLD | NEW |