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 "mojo/services/media/common/cpp/timeline.h" |
10 #include "services/media/audio/audio_output_manager.h" | 11 #include "services/media/audio/audio_output_manager.h" |
11 #include "services/media/audio/audio_server_impl.h" | 12 #include "services/media/audio/audio_server_impl.h" |
12 #include "services/media/audio/audio_track_impl.h" | 13 #include "services/media/audio/audio_track_impl.h" |
13 #include "services/media/audio/audio_track_to_output_link.h" | 14 #include "services/media/audio/audio_track_to_output_link.h" |
14 | 15 |
15 namespace mojo { | 16 namespace mojo { |
16 namespace media { | 17 namespace media { |
17 namespace audio { | 18 namespace audio { |
18 | 19 |
19 constexpr size_t AudioTrackImpl::PTS_FRACTIONAL_BITS; | 20 constexpr size_t AudioTrackImpl::PTS_FRACTIONAL_BITS; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 AudioTrackImplPtr ret(new AudioTrackImpl(iface.Pass(), owner)); | 66 AudioTrackImplPtr ret(new AudioTrackImpl(iface.Pass(), owner)); |
66 ret->weak_this_ = ret; | 67 ret->weak_this_ = ret; |
67 return ret; | 68 return ret; |
68 } | 69 } |
69 | 70 |
70 void AudioTrackImpl::Shutdown() { | 71 void AudioTrackImpl::Shutdown() { |
71 // If we are unbound, then we have already been shut down and are just waiting | 72 // If we are unbound, then we have already been shut down and are just waiting |
72 // for the service to destroy us. Run some DCHECK sanity checks and get out. | 73 // for the service to destroy us. Run some DCHECK sanity checks and get out. |
73 if (!binding_.is_bound()) { | 74 if (!binding_.is_bound()) { |
74 DCHECK(!pipe_.IsInitialized()); | 75 DCHECK(!pipe_.IsInitialized()); |
75 DCHECK(!rate_control_.is_bound()); | 76 DCHECK(!timeline_control_site_.is_bound()); |
76 DCHECK(!outputs_.size()); | 77 DCHECK(!outputs_.size()); |
77 return; | 78 return; |
78 } | 79 } |
79 | 80 |
80 // Close the connection to our client | 81 // Close the connection to our client |
81 binding_.set_connection_error_handler(mojo::Closure()); | 82 binding_.set_connection_error_handler(mojo::Closure()); |
82 binding_.Close(); | 83 binding_.Close(); |
83 | 84 |
84 // reset all of our internal state and close any other client connections in | 85 // reset all of our internal state and close any other client connections in |
85 // the process. | 86 // the process. |
86 pipe_.Reset(); | 87 pipe_.Reset(); |
87 rate_control_.Reset(); | 88 timeline_control_site_.Reset(); |
88 outputs_.clear(); | 89 outputs_.clear(); |
89 | 90 |
90 DCHECK(owner_); | 91 DCHECK(owner_); |
91 AudioTrackImplPtr thiz = weak_this_.lock(); | 92 AudioTrackImplPtr thiz = weak_this_.lock(); |
92 owner_->RemoveTrack(thiz); | 93 owner_->RemoveTrack(thiz); |
93 } | 94 } |
94 | 95 |
95 void AudioTrackImpl::Describe(const DescribeCallback& cbk) { | 96 void AudioTrackImpl::Describe(const DescribeCallback& cbk) { |
96 // Build a minimal descriptor | 97 // Build a minimal descriptor |
97 // | 98 // |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 static_cast<uint32_t>(configuration->audio_frame_ratio); | 187 static_cast<uint32_t>(configuration->audio_frame_ratio); |
187 uint32_t denominator = | 188 uint32_t denominator = |
188 static_cast<uint32_t>(configuration->media_time_ratio); | 189 static_cast<uint32_t>(configuration->media_time_ratio); |
189 if ((numerator < 1) || (denominator < 1)) { | 190 if ((numerator < 1) || (denominator < 1)) { |
190 LOG(ERROR) << "Invalid (audio frames:media time ticks) ratio (" | 191 LOG(ERROR) << "Invalid (audio frames:media time ticks) ratio (" |
191 << numerator << "/" << denominator << ")"; | 192 << numerator << "/" << denominator << ")"; |
192 Shutdown(); | 193 Shutdown(); |
193 return; | 194 return; |
194 } | 195 } |
195 | 196 |
| 197 frames_per_ns_ = |
| 198 TimelineRate(cfg->frames_per_second, Timeline::ns_from_seconds(1)); |
196 | 199 |
197 // Figure out the rate we need to scale by in order to produce our fixed | 200 // Figure out the rate we need to scale by in order to produce our fixed |
198 // point timestamps. | 201 // point timestamps. |
199 LinearTransform::Ratio frac_scale(1 << PTS_FRACTIONAL_BITS, 1); | 202 LinearTransform::Ratio frac_scale(1 << PTS_FRACTIONAL_BITS, 1); |
200 LinearTransform::Ratio frame_scale(LinearTransform::Ratio(numerator, | 203 LinearTransform::Ratio frame_scale(LinearTransform::Ratio(numerator, |
201 denominator)); | 204 denominator)); |
202 bool no_loss = LinearTransform::Ratio::Compose(frac_scale, | 205 bool no_loss = LinearTransform::Ratio::Compose(frac_scale, |
203 frame_scale, | 206 frame_scale, |
204 &frame_to_media_ratio_); | 207 &frame_to_media_ratio_); |
205 if (!no_loss) { | 208 if (!no_loss) { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 // implementations, and scheduling a job to recalculate the properties for the | 258 // implementations, and scheduling a job to recalculate the properties for the |
256 // dirty tracks and notify the users as appropriate. | 259 // dirty tracks and notify the users as appropriate. |
257 | 260 |
258 // If we cannot promote our own weak pointer, something is seriously wrong. | 261 // If we cannot promote our own weak pointer, something is seriously wrong. |
259 AudioTrackImplPtr strong_this(weak_this_.lock()); | 262 AudioTrackImplPtr strong_this(weak_this_.lock()); |
260 DCHECK(strong_this); | 263 DCHECK(strong_this); |
261 DCHECK(owner_); | 264 DCHECK(owner_); |
262 owner_->GetOutputManager().SelectOutputsForTrack(strong_this); | 265 owner_->GetOutputManager().SelectOutputsForTrack(strong_this); |
263 } | 266 } |
264 | 267 |
265 void AudioTrackImpl::GetRateControl(InterfaceRequest<RateControl> req) { | 268 void AudioTrackImpl::GetTimelineControlSite( |
266 if (!rate_control_.Bind(req.Pass())) { | 269 InterfaceRequest<MediaTimelineControlSite> req) { |
267 Shutdown(); | 270 timeline_control_site_.Bind(req.Pass()); |
268 } | |
269 } | 271 } |
270 | 272 |
271 void AudioTrackImpl::SetGain(float db_gain) { | 273 void AudioTrackImpl::SetGain(float db_gain) { |
272 if (db_gain >= AudioTrack::kMaxGain) { | 274 if (db_gain >= AudioTrack::kMaxGain) { |
273 LOG(ERROR) << "Gain value too large (" << db_gain << ") for audio track."; | 275 LOG(ERROR) << "Gain value too large (" << db_gain << ") for audio track."; |
274 Shutdown(); | 276 Shutdown(); |
275 return; | 277 return; |
276 } | 278 } |
277 | 279 |
278 db_gain_ = db_gain; | 280 db_gain_ = db_gain; |
(...skipping 20 matching lines...) Expand all Loading... |
299 if (iter != outputs_.end()) { | 301 if (iter != outputs_.end()) { |
300 outputs_.erase(iter); | 302 outputs_.erase(iter); |
301 } else { | 303 } else { |
302 // TODO(johngro): that's odd. I can't think of a reason why we we should | 304 // TODO(johngro): that's odd. I can't think of a reason why we we should |
303 // not be able to find this link in our set of outputs... should we log | 305 // not be able to find this link in our set of outputs... should we log |
304 // something about this? | 306 // something about this? |
305 DCHECK(false); | 307 DCHECK(false); |
306 } | 308 } |
307 } | 309 } |
308 | 310 |
| 311 void AudioTrackImpl::SnapshotRateTrans(LinearTransform* out, |
| 312 uint32_t* generation) { |
| 313 TimelineFunction timeline_function; |
| 314 timeline_control_site_.SnapshotCurrentFunction( |
| 315 Timeline::local_now(), &timeline_function, generation); |
| 316 |
| 317 // The control site works in ns units. We want the rate in frames per |
| 318 // nanosecond, so we convert here. |
| 319 TimelineRate rate_in_frames_per_ns = |
| 320 timeline_function.rate() * frames_per_ns_; |
| 321 |
| 322 *out = LinearTransform(timeline_function.reference_time(), |
| 323 rate_in_frames_per_ns.subject_delta(), |
| 324 rate_in_frames_per_ns.reference_delta(), |
| 325 timeline_function.subject_time() * frames_per_ns_); |
| 326 } |
| 327 |
309 void AudioTrackImpl::OnPacketReceived(AudioPipe::AudioPacketRefPtr packet) { | 328 void AudioTrackImpl::OnPacketReceived(AudioPipe::AudioPacketRefPtr packet) { |
310 DCHECK(packet); | 329 DCHECK(packet); |
311 for (const auto& output : outputs_) { | 330 for (const auto& output : outputs_) { |
312 DCHECK(output); | 331 DCHECK(output); |
313 output->PushToPendingQueue(packet); | 332 output->PushToPendingQueue(packet); |
314 } | 333 } |
315 } | 334 } |
316 | 335 |
317 bool AudioTrackImpl::OnFlushRequested(const MediaConsumer::FlushCallback& cbk) { | 336 bool AudioTrackImpl::OnFlushRequested(const MediaConsumer::FlushCallback& cbk) { |
318 for (const auto& output : outputs_) { | 337 for (const auto& output : outputs_) { |
319 DCHECK(output); | 338 DCHECK(output); |
320 output->FlushPendingQueue(); | 339 output->FlushPendingQueue(); |
321 } | 340 } |
322 cbk.Run(); | 341 cbk.Run(); |
323 return true; | 342 return true; |
324 } | 343 } |
325 | 344 |
326 } // namespace audio | 345 } // namespace audio |
327 } // namespace media | 346 } // namespace media |
328 } // namespace mojo | 347 } // namespace mojo |
OLD | NEW |