// 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.
closed 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.
    strict AddPayloadBuffer(resource struct {
        id uint32;
        payload_buffer zx.Handle:VMO;
    });

    /// 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.
    strict RemovePayloadBuffer(struct {
        id uint32;
    });
};

/// Consumes a stream of packets. This interface is typically inherited along
/// with `StreamBufferSet` to enable the transport of elementary streams from
/// clients to services.
closed 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.
    strict SendPacket(struct {
        packet StreamPacket;
    }) -> ();

    /// 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.
    strict SendPacketNoReply(struct {
        packet StreamPacket;
    });

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

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

    /// Discards packets previously sent via `SendPacket` or `SendPacketNoReply`
    /// and not yet released.
    strict 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.
closed 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.
    strict -> OnPacketProduced(struct {
        packet StreamPacket;
    });

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

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

    // 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.
    strict DiscardAllPackets() -> ();
    strict DiscardAllPacketsNoReply();
};

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

/// Describes a packet consumed by `StreamSink` or produced by `StreamSource`.
type StreamPacket = struct {
    /// Time at which the packet is to be presented, according to the
    /// presentation clock.
    @allow_deprecated_struct_defaults
    pts int64 = 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.
    payload_buffer_id uint32;

    /// 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.
    payload_offset uint64;

    /// 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.
    payload_size uint64;

    /// An bitwise-or'ed set of flags (see constants below) describing
    /// properties of this packet.
    @allow_deprecated_struct_defaults
    flags uint32 = 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.
    @allow_deprecated_struct_defaults
    buffer_config uint64 = 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.
    @allow_deprecated_struct_defaults
    stream_segment_id uint64 = 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 NO_TIMESTAMP int64 = 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 STREAM_PACKET_FLAG_KEY_FRAME uint32 = 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 STREAM_PACKET_FLAG_DROPPABLE uint32 = 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 STREAM_PACKET_FLAG_DISCONTINUITY uint32 = 0x04;
