blob: abb0a573884db2958b57dde6bad3735f3c3d4fb4 [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/lpcm_reformatter_impl.h"
#include "garnet/bin/media/fidl/fidl_type_conversions.h"
#include "lib/fxl/logging.h"
namespace media {
// static
std::shared_ptr<LpcmReformatterImpl> LpcmReformatterImpl::Create(
MediaTypePtr input_media_type,
AudioSampleFormat output_sample_format,
fidl::InterfaceRequest<MediaTypeConverter> request,
MediaServiceImpl* owner) {
return std::shared_ptr<LpcmReformatterImpl>(
new LpcmReformatterImpl(std::move(input_media_type), output_sample_format,
std::move(request), owner));
}
LpcmReformatterImpl::LpcmReformatterImpl(
MediaTypePtr input_media_type,
AudioSampleFormat output_sample_format,
fidl::InterfaceRequest<MediaTypeConverter> request,
MediaServiceImpl* owner)
: MediaServiceImpl::Product<MediaTypeConverter>(this,
std::move(request),
owner),
graph_(owner->multiproc_task_runner()),
consumer_(FidlPacketConsumer::Create()),
producer_(FidlPacketProducer::Create()) {
FXL_DCHECK(input_media_type);
FLOG(log_channel_, BoundAs(FLOG_BINDING_KOID(binding()), "lpcm_reformatter"));
std::unique_ptr<StreamType> input_stream_type =
input_media_type.To<std::unique_ptr<StreamType>>();
RCHECK(input_stream_type->medium() == StreamType::Medium::kAudio);
RCHECK(input_stream_type->audio() != nullptr);
reformatter_ = LpcmReformatter::Create(*input_stream_type->audio(),
Convert(output_sample_format));
FXL_DCHECK(reformatter_);
FLOG(log_channel_,
Config(std::move(input_media_type),
MediaType::From(reformatter_->output_stream_type()),
FLOG_ADDRESS(consumer_.get()), FLOG_ADDRESS(producer_.get())));
NodeRef consumer_ref = graph_.Add(consumer_);
NodeRef reformatter_ref = graph_.Add(reformatter_);
NodeRef producer_ref = graph_.Add(producer_);
graph_.ConnectNodes(consumer_ref, reformatter_ref);
graph_.ConnectNodes(reformatter_ref, producer_ref);
consumer_->SetFlushRequestedCallback(
[this, consumer_ref](bool hold_frame,
const MediaPacketConsumer::FlushCallback& callback) {
FXL_DCHECK(producer_);
graph_.FlushOutput(consumer_ref.output(), hold_frame);
producer_->FlushConnection(hold_frame, callback);
});
graph_.Prepare();
}
LpcmReformatterImpl::~LpcmReformatterImpl() {}
void LpcmReformatterImpl::GetOutputType(const GetOutputTypeCallback& callback) {
FXL_DCHECK(reformatter_);
callback(MediaType::From(reformatter_->output_stream_type()));
}
void LpcmReformatterImpl::GetPacketConsumer(
fidl::InterfaceRequest<MediaPacketConsumer> request) {
Retain();
consumer_->Bind(std::move(request), [this]() { Release(); });
}
void LpcmReformatterImpl::GetPacketProducer(
fidl::InterfaceRequest<MediaPacketProducer> request) {
producer_->Bind(std::move(request));
}
} // namespace media