blob: 2274654be1a1e0fdeb3b446c5d9a1c796ec09999 [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "garnet/bin/media/media_service/media_sink_impl.h"
#include "garnet/bin/media/fidl/fidl_conversion_pipeline_builder.h"
#include "garnet/bin/media/fidl/fidl_type_conversions.h"
#include "lib/fxl/functional/make_copyable.h"
#include "lib/fxl/logging.h"
namespace media {
// static
std::shared_ptr<MediaSinkImpl> MediaSinkImpl::Create(
fidl::InterfaceHandle<MediaRenderer> renderer_handle,
fidl::InterfaceRequest<MediaSink> sink_request,
MediaServiceImpl* owner) {
return std::shared_ptr<MediaSinkImpl>(new MediaSinkImpl(
std::move(renderer_handle), std::move(sink_request), owner));
}
MediaSinkImpl::MediaSinkImpl(
fidl::InterfaceHandle<MediaRenderer> renderer_handle,
fidl::InterfaceRequest<MediaSink> sink_request,
MediaServiceImpl* owner)
: MediaServiceImpl::Product<MediaSink>(this,
std::move(sink_request),
owner),
renderer_(renderer_handle.Bind()) {
FXL_DCHECK(renderer_);
FLOG(log_channel_, BoundAs(FLOG_BINDING_KOID(binding())));
media_service_ = owner->ConnectToEnvironmentService<MediaService>();
renderer_->GetSupportedMediaTypes([this](fidl::Array<MediaTypeSetPtr>
supported_media_types) {
FXL_DCHECK(supported_media_types);
supported_stream_types_ = supported_media_types.To<
std::unique_ptr<std::vector<std::unique_ptr<media::StreamTypeSet>>>>();
got_supported_stream_types_.Occur();
});
}
MediaSinkImpl::~MediaSinkImpl() {}
void MediaSinkImpl::GetTimelineControlPoint(
fidl::InterfaceRequest<MediaTimelineControlPoint> request) {
FXL_DCHECK(renderer_);
renderer_->GetTimelineControlPoint(std::move(request));
}
void MediaSinkImpl::ConsumeMediaType(MediaTypePtr media_type,
const ConsumeMediaTypeCallback& callback) {
if (consume_media_type_callback_) {
FXL_DLOG(ERROR) << "ConsumeMediaType called while already pending.";
callback(nullptr);
UnbindAndReleaseFromOwner();
return;
}
original_media_type_ = std::move(media_type);
stream_type_ = original_media_type_.To<std::unique_ptr<StreamType>>();
consume_media_type_callback_ = callback;
got_supported_stream_types_.When([this]() { BuildConversionPipeline(); });
}
void MediaSinkImpl::BuildConversionPipeline() {
BuildFidlConversionPipeline(
media_service_, *supported_stream_types_, nullptr,
[this](fidl::InterfaceRequest<MediaPacketConsumer> request) {
renderer_->GetPacketConsumer(std::move(request));
},
std::move(stream_type_),
[this](bool succeeded, const ConsumerGetter& consumer_getter,
const ProducerGetter& producer_getter,
std::unique_ptr<StreamType> stream_type,
std::vector<zx_koid_t> converter_koids) {
FXL_DCHECK(!producer_getter);
FXL_DCHECK(consume_media_type_callback_);
if (!succeeded) {
FXL_LOG(WARNING) << "Failed to create conversion pipeline.";
// TODO(dalesat): Log this to flog.
consume_media_type_callback_(nullptr);
consume_media_type_callback_ = nullptr;
original_media_type_.reset();
return;
}
FXL_DCHECK(consumer_getter);
stream_type_ = std::move(stream_type);
renderer_->SetMediaType(MediaType::From(stream_type_));
FLOG(log_channel_, Config(std::move(original_media_type_),
MediaType::From(stream_type_),
fidl::Array<uint64_t>::From(converter_koids),
FLOG_PTR_KOID(renderer_)));
// Not needed anymore.
original_media_type_.reset();
MediaPacketConsumerPtr consumer;
consumer_getter(consumer.NewRequest());
consume_media_type_callback_(std::move(consumer));
consume_media_type_callback_ = nullptr;
});
}
} // namespace media