| // Copyright 2018 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/mediaplayer/core/renderer_sink_segment.h" |
| |
| #include "garnet/bin/mediaplayer/core/conversion_pipeline_builder.h" |
| #include "garnet/bin/mediaplayer/graph/types/stream_type.h" |
| #include "lib/fxl/functional/make_copyable.h" |
| #include "lib/fxl/logging.h" |
| |
| namespace media_player { |
| |
| // static |
| std::unique_ptr<RendererSinkSegment> RendererSinkSegment::Create( |
| std::shared_ptr<Renderer> renderer, DecoderFactory* decoder_factory) { |
| return std::make_unique<RendererSinkSegment>(renderer, decoder_factory); |
| } |
| |
| RendererSinkSegment::RendererSinkSegment(std::shared_ptr<Renderer> renderer, |
| DecoderFactory* decoder_factory) |
| : renderer_(renderer), decoder_factory_(decoder_factory) { |
| FXL_DCHECK(renderer_); |
| FXL_DCHECK(decoder_factory_); |
| } |
| |
| RendererSinkSegment::~RendererSinkSegment() {} |
| |
| void RendererSinkSegment::DidProvision() { |
| renderer_node_ = graph().Add(renderer_); |
| |
| renderer_->Provision(dispatcher(), [this]() { NotifyUpdate(); }); |
| } |
| |
| void RendererSinkSegment::WillDeprovision() { |
| renderer_->Deprovision(); |
| |
| if (renderer_node_) { |
| graph().RemoveNode(renderer_node_); |
| renderer_node_ = nullptr; |
| } |
| } |
| |
| void RendererSinkSegment::Connect(const StreamType& type, OutputRef output, |
| ConnectCallback callback) { |
| FXL_DCHECK(provisioned()); |
| FXL_DCHECK(renderer_); |
| FXL_DCHECK(renderer_node_); |
| |
| connected_output_ = nullptr; |
| |
| BuildConversionPipeline( |
| type, renderer_->GetSupportedStreamTypes(), &graph(), decoder_factory_, |
| output, |
| [this, callback = std::move(callback), |
| is_audio = type.medium() == StreamType::Medium::kAudio]( |
| OutputRef output, std::unique_ptr<StreamType> stream_type) { |
| if (!stream_type) { |
| ReportProblem( |
| is_audio |
| ? fuchsia::mediaplayer::kProblemAudioEncodingNotSupported |
| : fuchsia::mediaplayer::kProblemVideoEncodingNotSupported, |
| ""); |
| callback(Result::kUnsupportedOperation); |
| return; |
| } |
| |
| graph().ConnectOutputToNode(output, renderer_node_); |
| connected_output_ = output; |
| renderer_->SetStreamType(*stream_type); |
| callback(Result::kOk); |
| }); |
| } |
| |
| void RendererSinkSegment::Disconnect() { |
| FXL_DCHECK(provisioned()); |
| FXL_DCHECK(renderer_node_); |
| FXL_DCHECK(connected_output_); |
| |
| // TODO(dalesat): Consider keeping the conversions until we know they won't |
| // work for the next connection. |
| |
| graph().DisconnectOutput(connected_output_); |
| graph().RemoveNodesConnectedToInput(renderer_node_.input()); |
| |
| connected_output_ = nullptr; |
| } |
| |
| void RendererSinkSegment::Prime(fit::closure callback) { |
| FXL_DCHECK(renderer_); |
| renderer_->Prime(std::move(callback)); |
| } |
| |
| void RendererSinkSegment::SetTimelineFunction( |
| media::TimelineFunction timeline_function, fit::closure callback) { |
| FXL_DCHECK(renderer_); |
| renderer_->SetTimelineFunction(timeline_function, std::move(callback)); |
| } |
| |
| void RendererSinkSegment::SetProgramRange(uint64_t program, int64_t min_pts, |
| int64_t max_pts) { |
| FXL_DCHECK(renderer_); |
| renderer_->SetProgramRange(program, min_pts, max_pts); |
| } |
| |
| } // namespace media_player |