// 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.

library fuchsia.media;

// fuchsia.media contains definitions shared by the various fuchsia.media.*
// libraries. Definitions in this file concern the transport of elementary
// streams between clients and services.

/// Manages a set of payload buffers for a stream. This interface is typically
/// inherited along with `StreamSink` or `StreamSource` to enable the transport
/// of elementary streams between clients and services.
[FragileBase]
protocol StreamBufferSet {
    /// Adds a payload buffer to the current buffer set associated with the
    /// connection. A `StreamPacket` struct reference a payload buffer in the
    /// current set by ID using the `StreamPacket.payload_buffer_id` field.
    ///
    /// A buffer with ID `id` must not be in the current set when this method is
    /// invoked, otherwise the service will close the connection.
    AddPayloadBuffer(uint32 id, handle<vmo> payload_buffer);

    /// Removes a payload buffer from the current buffer set associated with the
    /// connection.
    ///
    /// A buffer with ID `id` must exist in the current set when this method is
    /// invoked, otherwise the service will will close the connection.
    RemovePayloadBuffer(uint32 id);
};

/// Consumes a stream of packets. This interface is typically inherited along
/// with `StreamBufferSet` to enable the transport of elementary streams from
/// clients to services.
[FragileBase]
protocol StreamSink {
    /// Sends a packet to the service. The response is sent when the service is
    /// done with the associated payload memory.
    ///
    /// `packet` must be valid for the current buffer set, otherwise the service
    /// will close the connection.
    SendPacket(StreamPacket packet) -> ();

    /// Sends a packet to the service. This interface doesn't define how the
    /// client knows when the sink is done with the associated payload memory.
    /// The inheriting interface must define that.
    ///
    /// `packet` must be valid for the current buffer set, otherwise the service
    /// will close the connection.
    SendPacketNoReply(StreamPacket packet);

    /// Indicates the stream has ended. The precise semantics of this method are
    /// determined by the inheriting interface.
    EndOfStream();

    /// Discards packets previously sent via `SendPacket` or `SendPacketNoReply`
    /// and not yet released. The response is sent after all packets have been
    /// released.
    DiscardAllPackets() -> ();

    /// Discards packets previously sent via `SendPacket` or `SendPacketNoReply`
    /// and not yet released.
    DiscardAllPacketsNoReply();
};

/// Produces a stream of packets. This interface is typically inherited along
/// with `StreamBufferSet` to enable the transport of elementary streams from
/// services to clients.
[FragileBase]
protocol StreamSource {
    /// Delivers a packet produced by the service. When the client is done with
    /// the payload memory, the client must call `ReleasePacket` to release the
    /// payload memory.
    -> OnPacketProduced(StreamPacket packet);

    /// Indicates that the stream has ended.
    -> OnEndOfStream();

    /// Releases payload memory associated with a packet previously delivered
    /// via `OnPacketProduced`.
    ReleasePacket(StreamPacket packet);

    // These methods were mistakenly copied from `StreamSink` and are intended
    // to be analogs of the `StreamSink` methods. In order to function as
    // analogs, they would need to be an event (e.g., `OnDiscardAllPackets`).
    // That event would notify the client that it should release all packets
    // delivered via `OnPacketProduced` that have not already been released.
    // Currently, these methods are used in `AudioCapturer` to indicate that
    // the service should cancel all unfulfilled `CaptureAt` requests. A
    // new method should be created for that purpose.
    // TODO(dalesat): This should be an event.
    DiscardAllPackets() -> ();
    DiscardAllPacketsNoReply();
};

/// A StreamSink that uses StreamBufferSet for buffer management.
protocol SimpleStreamSink {
    compose StreamBufferSet;
    compose StreamSink;
};

/// Describes a packet consumed by `StreamSink` or produced by `StreamSource`.
struct StreamPacket {
    /// Time at which the packet is to be presented, according to the
    /// presentation clock.
    int64 pts = NO_TIMESTAMP;

    /// ID of the payload buffer used for this packet.
    ///
    /// When this struct is used with `StreamBufferSet`, this field is the ID of
    /// a payload buffer provided via `StreamBufferSet.AddPayloadBuffer`. In
    /// that case, this value must identify a payload buffer in the current set.
    /// Other interfaces may define different semantics for this field.
    uint32 payload_buffer_id;

    /// Offset of the packet payload in the payload buffer.
    ///
    /// This value plus the `payload_size` value must be less than or equal to
    /// the size of the referenced payload buffer.
    uint64 payload_offset;

    /// Size in bytes of the payload.
    ///
    /// This value plus the `payload_offest` value must be less than or equal to
    /// the size of the referenced payload buffer.
    uint64 payload_size;

    /// An bitwise-or'ed set of flags (see constants below) describing
    /// properties of this packet.
    uint32 flags = 0;

    /// The buffer configuration associated with this packet. The semantics of
    /// this field depend on the interface with which this struct is used.
    /// In many contexts, this field is not used. This field is intended for
    /// situations in which buffer configurations (i.e. sets of payload buffers)
    /// are explicitly identified. In such cases, the `payload_buffer_id` refers
    /// to a payload buffer in the buffer configuration identified by this
    /// field.
    uint64 buffer_config = 0;

    /// The stream segment associated with this packet. The semantics of this
    /// field depend on the interface with which this struct is used. In many
    /// contexts, this field is not used. This field is intended to distinguish
    /// contiguous segments of the stream where stream properties (e.g.
    /// encoding) may differ from segment to segment.
    uint64 stream_segment_id = 0;
};

/// `StreamPacket.flags` values.

/// When used as a `StreamPacket.pts` value, indicates that the packet has no
/// specific presentation timestamp. The effective presentation time of such a
/// packet depends on the context in which the `StreamPacket` is used.
const int64 NO_TIMESTAMP = 0x7fffffffffffffff;

/// Indicates that the packet can be understood without reference to other
/// packets in the stream. This is typically used in compressed streams to
/// identify packets that contain key frames.
const uint32 STREAM_PACKET_FLAG_KEY_FRAME = 0x01;

/// Indicates that all other packets in the stream can be understood without
/// reference to this packet. This is typically used in compressed streams to
/// identify packets containing frames that may be discarded without affecting
/// other frames.
const uint32 STREAM_PACKET_FLAG_DROPPABLE = 0x02;

/// Indicates a discontinuity in an otherwise continuous-in-time sequence of
/// packets. The precise semantics of this flag depend on the context in which
/// the `StreamPacket` is used.
const uint32 STREAM_PACKET_FLAG_DISCONTINUITY = 0x04;