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

using zx;

// 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.
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, zx.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.
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.
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;
};

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

// `StreamPacket.flags` values.
//
/// 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;
