| Index: services/media/audio/audio_track_impl.cc
|
| diff --git a/services/media/audio/audio_track_impl.cc b/services/media/audio/audio_track_impl.cc
|
| index 55519aa9b87dc92d26333ac6443fa0f822525afb..fc1565c62d310a8474f9c668daeb825bf2d7a617 100644
|
| --- a/services/media/audio/audio_track_impl.cc
|
| +++ b/services/media/audio/audio_track_impl.cc
|
| @@ -44,34 +44,51 @@ static const struct {
|
| },
|
| };
|
|
|
| -AudioTrackImpl::AudioTrackImpl(InterfaceRequest<AudioTrack> iface,
|
| +AudioTrackImpl::AudioTrackImpl(InterfaceRequest<AudioTrack> track_request,
|
| + InterfaceRequest<MediaRenderer> renderer_request,
|
| AudioServerImpl* owner)
|
| : owner_(owner),
|
| - binding_(this),
|
| + track_binding_(this, track_request.Pass()),
|
| + renderer_binding_(this, renderer_request.Pass()),
|
| pipe_(this, owner) {
|
| CHECK(nullptr != owner_);
|
| - binding_.Bind(iface.Pass());
|
| - binding_.set_connection_error_handler([this]() -> void {
|
| - Shutdown();
|
| + track_binding_.set_connection_error_handler([this]() -> void {
|
| + if (!renderer_binding_.is_bound()) {
|
| + Shutdown();
|
| + }
|
| + });
|
| + renderer_binding_.set_connection_error_handler([this]() -> void {
|
| + if (!track_binding_.is_bound()) {
|
| + Shutdown();
|
| + }
|
| });
|
| }
|
|
|
| AudioTrackImpl::~AudioTrackImpl() {
|
| // assert that we have been cleanly shutdown already.
|
| - MOJO_DCHECK(!binding_.is_bound());
|
| + MOJO_DCHECK(!track_binding_.is_bound());
|
| + MOJO_DCHECK(!renderer_binding_.is_bound());
|
| }
|
|
|
| -AudioTrackImplPtr AudioTrackImpl::Create(InterfaceRequest<AudioTrack> iface,
|
| - AudioServerImpl* owner) {
|
| - AudioTrackImplPtr ret(new AudioTrackImpl(iface.Pass(), owner));
|
| +AudioTrackImplPtr AudioTrackImpl::Create(
|
| + InterfaceRequest<AudioTrack> track_request,
|
| + InterfaceRequest<MediaRenderer> renderer_request,
|
| + AudioServerImpl* owner) {
|
| + AudioTrackImplPtr ret(
|
| + new AudioTrackImpl(track_request.Pass(), renderer_request.Pass(), owner));
|
| ret->weak_this_ = ret;
|
| return ret;
|
| }
|
|
|
| void AudioTrackImpl::Shutdown() {
|
| + if (track_binding_.is_bound()) {
|
| + track_binding_.set_connection_error_handler(mojo::Closure());
|
| + track_binding_.Close();
|
| + }
|
| +
|
| // If we are unbound, then we have already been shut down and are just waiting
|
| // for the service to destroy us. Run some DCHECK sanity checks and get out.
|
| - if (!binding_.is_bound()) {
|
| + if (!renderer_binding_.is_bound()) {
|
| DCHECK(!pipe_.IsInitialized());
|
| DCHECK(!timeline_control_site_.is_bound());
|
| DCHECK(!outputs_.size());
|
| @@ -79,8 +96,8 @@ void AudioTrackImpl::Shutdown() {
|
| }
|
|
|
| // Close the connection to our client
|
| - binding_.set_connection_error_handler(mojo::Closure());
|
| - binding_.Close();
|
| + renderer_binding_.set_connection_error_handler(mojo::Closure());
|
| + renderer_binding_.Close();
|
|
|
| // reset all of our internal state and close any other client connections in
|
| // the process.
|
| @@ -93,7 +110,8 @@ void AudioTrackImpl::Shutdown() {
|
| owner_->RemoveTrack(thiz);
|
| }
|
|
|
| -void AudioTrackImpl::Describe(const DescribeCallback& cbk) {
|
| +void AudioTrackImpl::GetSupportedMediaTypes(
|
| + const GetSupportedMediaTypesCallback& cbk) {
|
| // Build a minimal descriptor
|
| //
|
| // TODO(johngro): one day, we need to make this description much more rich and
|
| @@ -106,14 +124,12 @@ void AudioTrackImpl::Describe(const DescribeCallback& cbk) {
|
| // message, but the nature of the structures generated by the C++ bindings
|
| // make this difficult. For now, we just create a trivial descriptor entierly
|
| // by hand.
|
| - AudioTrackDescriptorPtr desc(AudioTrackDescriptor::New());
|
| -
|
| - desc->supported_media_types =
|
| + Array<MediaTypeSetPtr> supported_media_types =
|
| Array<MediaTypeSetPtr>::New(arraysize(kSupportedAudioTypeSets));
|
|
|
| - for (size_t i = 0; i < desc->supported_media_types.size(); ++i) {
|
| + for (size_t i = 0; i < supported_media_types.size(); ++i) {
|
| const MediaTypeSetPtr& mts =
|
| - (desc->supported_media_types[i] = MediaTypeSet::New());
|
| + (supported_media_types[i] = MediaTypeSet::New());
|
|
|
| mts->medium = MediaTypeMedium::AUDIO;
|
| mts->encodings = Array<String>::New(1);
|
| @@ -132,11 +148,10 @@ void AudioTrackImpl::Describe(const DescribeCallback& cbk) {
|
| mts->details->set_audio(audio_detail.Pass());
|
| }
|
|
|
| - cbk.Run(desc.Pass());
|
| + cbk.Run(supported_media_types.Pass());
|
| }
|
|
|
| -void AudioTrackImpl::Configure(AudioTrackConfigurationPtr configuration,
|
| - InterfaceRequest<MediaConsumer> req) {
|
| +void AudioTrackImpl::SetMediaType(MediaTypePtr media_type) {
|
| // Are we already configured?
|
| if (pipe_.IsInitialized()) {
|
| LOG(ERROR) << "Attempting to reconfigure a configured audio track.";
|
| @@ -145,9 +160,9 @@ void AudioTrackImpl::Configure(AudioTrackConfigurationPtr configuration,
|
| }
|
|
|
| // Check the requested configuration.
|
| - if ((configuration->media_type->medium != MediaTypeMedium::AUDIO) ||
|
| - (configuration->media_type->encoding != MediaType::kAudioEncodingLpcm) ||
|
| - (!configuration->media_type->details->is_audio())) {
|
| + if ((media_type->medium != MediaTypeMedium::AUDIO) ||
|
| + (media_type->encoding != MediaType::kAudioEncodingLpcm) ||
|
| + (!media_type->details->is_audio())) {
|
| LOG(ERROR) << "Unsupported configuration requested in "
|
| "AudioTrack::Configure. Media type must be LPCM audio.";
|
| Shutdown();
|
| @@ -156,7 +171,7 @@ void AudioTrackImpl::Configure(AudioTrackConfigurationPtr configuration,
|
|
|
| // Search our supported configuration sets to find one compatible with this
|
| // request.
|
| - auto& cfg = configuration->media_type->details->get_audio();
|
| + auto& cfg = media_type->details->get_audio();
|
| size_t i;
|
| for (i = 0; i < arraysize(kSupportedAudioTypeSets); ++i) {
|
| const auto& cfg_set = kSupportedAudioTypeSets[i];
|
| @@ -182,32 +197,18 @@ void AudioTrackImpl::Configure(AudioTrackConfigurationPtr configuration,
|
| return;
|
| }
|
|
|
| - // Sanity check the ratio which relates audio frames to media time.
|
| - uint32_t numerator =
|
| - static_cast<uint32_t>(configuration->audio_frame_ratio);
|
| - uint32_t denominator =
|
| - static_cast<uint32_t>(configuration->media_time_ratio);
|
| - if ((numerator < 1) || (denominator < 1)) {
|
| - LOG(ERROR) << "Invalid (audio frames:media time ticks) ratio ("
|
| - << numerator << "/" << denominator << ")";
|
| - Shutdown();
|
| - return;
|
| - }
|
| -
|
| frames_per_ns_ =
|
| TimelineRate(cfg->frames_per_second, Timeline::ns_from_seconds(1));
|
|
|
| // Figure out the rate we need to scale by in order to produce our fixed
|
| // point timestamps.
|
| LinearTransform::Ratio frac_scale(1 << PTS_FRACTIONAL_BITS, 1);
|
| - LinearTransform::Ratio frame_scale(LinearTransform::Ratio(numerator,
|
| - denominator));
|
| + LinearTransform::Ratio frame_scale(LinearTransform::Ratio(1, 1));
|
| bool no_loss = LinearTransform::Ratio::Compose(frac_scale,
|
| frame_scale,
|
| &frame_to_media_ratio_);
|
| if (!no_loss) {
|
| - LOG(ERROR) << "Invalid (audio frames:media time ticks) ratio ("
|
| - << numerator << "/" << denominator << ")";
|
| + LOG(ERROR) << "Invalid (audio frames:media time ticks) ratio (1/1)";
|
| Shutdown();
|
| return;
|
| }
|
| @@ -234,13 +235,6 @@ void AudioTrackImpl::Configure(AudioTrackConfigurationPtr configuration,
|
| }
|
| bytes_per_frame_ *= cfg->channels;
|
|
|
| - // Bind our pipe to the interface request.
|
| - if (pipe_.Init(req.Pass()) != MOJO_RESULT_OK) {
|
| - LOG(ERROR) << "Failed to media pipe to interface request.";
|
| - Shutdown();
|
| - return;
|
| - }
|
| -
|
| // Stash our configuration.
|
| format_ = cfg.Pass();
|
|
|
| @@ -265,6 +259,16 @@ void AudioTrackImpl::Configure(AudioTrackConfigurationPtr configuration,
|
| owner_->GetOutputManager().SelectOutputsForTrack(strong_this);
|
| }
|
|
|
| +void AudioTrackImpl::GetConsumer(
|
| + InterfaceRequest<MediaConsumer> consumer_request) {
|
| + // Bind our pipe to the interface request.
|
| + if (pipe_.Init(consumer_request.Pass()) != MOJO_RESULT_OK) {
|
| + LOG(ERROR) << "Failed to media pipe to interface request.";
|
| + Shutdown();
|
| + return;
|
| + }
|
| +}
|
| +
|
| void AudioTrackImpl::GetTimelineControlSite(
|
| InterfaceRequest<MediaTimelineControlSite> req) {
|
| timeline_control_site_.Bind(req.Pass());
|
|
|