blob: b55c3f9ba188a7331e6e87a8254fdecdfb18bb15 [file] [log] [blame]
// 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.
#ifndef SRC_MEDIA_PLAYBACK_MEDIAPLAYER_SOURCE_IMPL_H_
#define SRC_MEDIA_PLAYBACK_MEDIAPLAYER_SOURCE_IMPL_H_
#include <fuchsia/media/playback/cpp/fidl.h>
#include <vector>
#include "lib/fidl/cpp/binding.h"
#include "lib/fidl/cpp/binding_set.h"
#include "src/media/playback/mediaplayer/core/demux_source_segment.h"
#include "src/media/playback/mediaplayer/core/elementary_source_segment.h"
#include "src/media/playback/mediaplayer/demux/demux.h"
#include "src/media/playback/mediaplayer/graph/graph.h"
namespace media_player {
// Base class for fidl agents that represent a source of content that may be
// played.
class SourceImpl {
public:
SourceImpl(Graph* graph, fit::closure connection_failure_callback);
virtual ~SourceImpl();
// Removes and returns the |SourceSegment| hosted by this |SourceImpl|.
virtual std::unique_ptr<SourceSegment> TakeSourceSegment() = 0;
protected:
// Completes construction.
void CompleteConstruction(SourceSegment* source_segment);
// Sends status updates to clients.
virtual void SendStatusUpdates();
// Returns the current status of the source.
fuchsia::media::playback::SourceStatus& status() { return status_; }
// Clears |source_segment_|, |streams_| and |status_|.
void Clear();
// Calls the remove callback, if there is one.
void Remove();
private:
struct Stream {
std::unique_ptr<StreamType> stream_type_;
OutputRef output_;
};
// Handles a stream update from the source segment.
void OnStreamUpdated(size_t index, const SourceSegment::Stream& stream);
// Handles a stream removal from the source segment.
void OnStreamRemoved(size_t index);
// Updates |status_|.
void UpdateStatus();
SourceSegment* source_segment_;
Graph* graph_;
fit::closure connection_failure_callback_;
async_dispatcher_t* dispatcher_;
// TODO(dalesat): Do we really need to maintain this or can we just have an
// abstract GetStreams()?
std::vector<Stream> streams_;
fuchsia::media::playback::SourceStatus status_;
};
////////////////////////////////////////////////////////////////////////////////
// DemuxSourceImpl declaration.
// |SourceImpl| that hosts a |DemuxSourceSegment|.
class DemuxSourceImpl : public SourceImpl,
public fuchsia::media::playback::Source {
public:
// Creates a |DemuxSourceImpl|. |request| is optional.
// |connection_failure_callback|, which is also optional, allows the source
// to signal that its connection has failed.
static std::unique_ptr<DemuxSourceImpl> Create(
std::shared_ptr<Demux> demux, Graph* graph,
fidl::InterfaceRequest<fuchsia::media::playback::Source> request,
fit::closure connection_failure_callback);
DemuxSourceImpl(
std::shared_ptr<Demux> demux, Graph* graph,
fidl::InterfaceRequest<fuchsia::media::playback::Source> request,
fit::closure connection_failure_callback);
~DemuxSourceImpl() override;
// SourceImpl overrides.
std::unique_ptr<SourceSegment> TakeSourceSegment() override;
void SendStatusUpdates() override;
// Source implementation (Source has no methods).
private:
std::shared_ptr<Demux> demux_;
fidl::Binding<fuchsia::media::playback::Source> binding_;
std::unique_ptr<DemuxSourceSegment> demux_source_segment_;
};
////////////////////////////////////////////////////////////////////////////////
// ElementarySourceImpl declaration.
// |SourceImpl| that hosts a |ElementarySourceSegment|.
class ElementarySourceImpl : public SourceImpl,
public fuchsia::media::playback::ElementarySource {
public:
// Creates a |ElementarySourceImpl|. |request| is required.
// |connection_failure_callback|, which is also optional, allows the source
// to signal that its connection has failed.
static std::unique_ptr<ElementarySourceImpl> Create(
int64_t duration_ns, bool can_pause, bool can_seek,
std::unique_ptr<fuchsia::media::Metadata> metadata, Graph* graph,
fidl::InterfaceRequest<fuchsia::media::playback::ElementarySource>
request,
fit::closure connection_failure_callback);
ElementarySourceImpl(
int64_t duration_ns, bool can_pause, bool can_seek,
std::unique_ptr<fuchsia::media::Metadata> metadata, Graph* graph,
fidl::InterfaceRequest<fuchsia::media::playback::ElementarySource>
request,
fit::closure connection_failure_callback);
~ElementarySourceImpl() override;
// SourceImpl overrides.
std::unique_ptr<SourceSegment> TakeSourceSegment() override;
void SendStatusUpdates() override;
// ElementarySource implementation.
void AddStream(fuchsia::media::StreamType type,
uint32_t tick_per_second_numerator,
uint32_t tick_per_second_denominator,
::fidl::InterfaceRequest<fuchsia::media::SimpleStreamSink>
simple_stream_sink_request) override;
void AddBinding(
fidl::InterfaceRequest<fuchsia::media::playback::ElementarySource>
elementary_source_request) override;
private:
void AddBindingInternal(
fidl::InterfaceRequest<fuchsia::media::playback::ElementarySource>
elementary_source_request);
fidl::BindingSet<fuchsia::media::playback::ElementarySource> bindings_;
std::unique_ptr<ElementarySourceSegment> elementary_source_segment_;
ElementarySourceSegment* elementary_source_segment_raw_ptr_;
};
} // namespace media_player
#endif // SRC_MEDIA_PLAYBACK_MEDIAPLAYER_SOURCE_IMPL_H_