blob: 4f723a2eeb31f5367f40c33bfb3fc91e70a9e0b5 [file] [log] [blame]
// Copyright 2024 The Chromium 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 QUICHE_QUIC_MOQT_MOQT_PUBLISHER_H_
#define QUICHE_QUIC_MOQT_MOQT_PUBLISHER_H_
#include <cstdint>
#include <memory>
#include <optional>
#include "absl/base/nullability.h"
#include "quiche/quic/core/quic_time.h"
#include "quiche/quic/moqt/moqt_fetch_task.h"
#include "quiche/quic/moqt/moqt_messages.h"
#include "quiche/quic/moqt/moqt_object.h"
#include "quiche/quic/moqt/moqt_priority.h"
#include "quiche/quic/moqt/moqt_session_interface.h"
#include "quiche/quic/moqt/moqt_track.h"
#include "quiche/web_transport/web_transport.h"
namespace moqt {
// MoqtObjectListener is an interface for any entity that is listening for
// incoming objects for a given track.
class MoqtObjectListener {
public:
virtual ~MoqtObjectListener() = default;
// Called when the publisher is sure that it can serve the subscription. This
// could happen synchronously or asynchronously.Details necessary for the
// SUBSCRIBE_OK can be obtained from the MoqtTrackPublisher.
virtual void OnSubscribeAccepted() = 0;
// Called when the publisher is sure that it cannot serve the subscription.
// This could happen synchronously or asynchronously.
virtual void OnSubscribeRejected(MoqtSubscribeErrorReason reason) = 0;
// Notifies that a new object is available on the track. The object payload
// itself may be retrieved via GetCachedObject method of the associated track
// publisher.
virtual void OnNewObjectAvailable(Location sequence, uint64_t subgroup,
MoqtPriority publisher_priority) = 0;
// Notifies that a pure FIN has arrived following |sequence|. Should not be
// called unless all objects have already been delivered. If not delivered,
// instead set the fin_after_this flag in the PublishedObject.
virtual void OnNewFinAvailable(Location final_object_in_subgroup,
uint64_t subgroup_id) = 0;
// Notifies that the a stream is being abandoned (via RESET_STREAM) before
// all objects are delivered.
virtual void OnSubgroupAbandoned(
uint64_t group, uint64_t subgroup,
webtransport::StreamErrorCode error_code) = 0;
// No further object will be published for the given group, usually due to a
// timeout. The owner of the Listener may want to reset the relevant streams.
virtual void OnGroupAbandoned(uint64_t group_id) = 0;
// Notifies that the Publisher is being destroyed, so no more objects are
// coming.
virtual void OnTrackPublisherGone() = 0;
};
// MoqtTrackPublisher is an application-side API for an MoQT publisher
// of a single individual track.
class MoqtTrackPublisher {
public:
virtual ~MoqtTrackPublisher() = default;
// Returns the full name of the associated track.
virtual const FullTrackName& GetTrackName() const = 0;
// GetCachedObject lets the MoQT stack access the objects that are available
// in the track's built-in local cache. Retrieves the first object ID >=
// min_object that matches (sequence.group, sequence.subgroup).
//
// This implementation of MoQT does not store any objects within the MoQT
// stack itself, at least until the object is fully serialized and passed to
// the QUIC stack. Instead, it relies on individual tracks having a shared
// cache for recent objects, and objects are always pulled from that cache
// whenever they are sent. Once an object is not available via the cache, it
// can no longer be sent; this ensures that objects are not buffered forever.
//
// This method returns nullopt if the object is not currently available, but
// might become available in the future. If the object is gone forever,
// kEndOfGroup/kObjectDoesNotExist has to be returned instead;
// otherwise, the corresponding QUIC streams will be stuck waiting for objects
// that will never arrive.
virtual std::optional<PublishedObject> GetCachedObject(
uint64_t group, uint64_t subgroup, uint64_t min_object) const = 0;
// Registers a listener with the track. The listener will be notified of all
// newly arriving objects. The pointer to the listener must be valid until
// removed.
virtual void AddObjectListener(MoqtObjectListener* listener) = 0;
virtual void RemoveObjectListener(MoqtObjectListener* listener) = 0;
// Methods to return various track properties. Returns nullopt if the value is
// not yet available. Guaranteed to be non-null if an object is available
// and/or OnSubscribeAccepted() has been called.
// Track alias is not present because MoqtSession always uses locally
// generated values.
virtual std::optional<Location> largest_location() const = 0;
virtual std::optional<MoqtForwardingPreference> forwarding_preference()
const = 0;
virtual std::optional<MoqtDeliveryOrder> delivery_order() const = 0;
virtual std::optional<quic::QuicTimeDelta> expiration() const = 0;
// Performs a fetch for the specified range of objects.
virtual std::unique_ptr<MoqtFetchTask> StandaloneFetch(
Location start, Location end, std::optional<MoqtDeliveryOrder> order) = 0;
virtual std::unique_ptr<MoqtFetchTask> RelativeFetch(
uint64_t group_diff, std::optional<MoqtDeliveryOrder> order) = 0;
virtual std::unique_ptr<MoqtFetchTask> AbsoluteFetch(
uint64_t group, std::optional<MoqtDeliveryOrder> order) = 0;
};
// MoqtSession delivers a NamespaceListener to a TrackPublisher to receive
// notifications that sub-namespaces are available, and receive tracks that
// are published within that namespace. This generally occurs when the session
// receives a SUBSCRIBE_NAMESPACE message.
class NamespaceListener {
public:
virtual ~NamespaceListener() = default;
// Called when a namespace is published. Will generally result in the
// receiving session sending a PUBLISH_NAMESPACE message.
virtual void OnNamespacePublished(const TrackNamespace& track_namespace) = 0;
// Called when a namespace is no longer available. Will generally result in
// the receiving session sending a PUBLISH_NAMESPACE_DONE message.
virtual void OnNamespaceDone(const TrackNamespace& track_namespace) = 0;
// Called when a track is published within the namespace. Will generally
// result in the receiving session sending a PUBLISH message. Track APIs are
// available in |publisher|.
virtual void OnTrackPublished(
std::shared_ptr<MoqtTrackPublisher> publisher) = 0;
};
// MoqtPublisher is an interface to a publisher that allows it to publish
// multiple tracks.
class MoqtPublisher {
public:
virtual ~MoqtPublisher() = default;
// These are all called by MoqtSession based on messages arriving on the wire.
virtual absl_nullable std::shared_ptr<MoqtTrackPublisher> GetTrack(
const FullTrackName& track_name) = 0;
virtual void AddNamespaceListener(NamespaceListener* listener) = 0;
virtual void RemoveNamespaceListener(NamespaceListener* listener) = 0;
};
} // namespace moqt
#endif // QUICHE_QUIC_MOQT_MOQT_PUBLISHER_H_