| 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 |