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

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

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

    /// Releases payload memory associated with a packet previously delivered
    /// via `OnPacketProduced`.
    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.
    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`.
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;
