// Copyright 2021 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.media2;

using fuchsia.mediastreams;
using zx;

/// The maximum number of `PayloadRange`s allowed per `Packet`.
const MAX_PAYLOAD_RANGES int64 = 16;

/// The maximum number of `EncryptionSubsampleEntry`s allowed.
const MAX_SUBSAMPLE_ENTRIES int64 = 16;

/// A packet consumer for cross-process elementary stream transport.
protocol StreamSink {
    /// Puts a packet to the sink.
    ///
    /// + request `packet` structure describing the packet to put.
    /// + request `release_fence` eventpair closed when the consumer
    ///   is done with the packet and the buffer regions associated with
    ///   the packet may be reused. Packets may be released in any order.
    ///   The release fence may be duplicated as needed. When the last
    ///   copy of the eventpair has been destroyed, the client receives
    ///   `ZX_EVENTPAIR_PEER_CLOSED` on the peer of `release_fence`.
    PutPacket(resource struct {
        packet Packet;
        release_fence zx.handle:EVENTPAIR;
    });

    /// Indicates that the end of the stream has been reached.
    /// Consumers such as audio and video renderers signal their
    /// clients when the last packet before end-of-stream has been
    /// rendered, so the client knows when to, for example, change
    /// the UI state of a player to let the user know the content is
    /// done playing. Packets may arrive after `End` is received, e.g.
    /// when a seek occurs.
    End();

    /// Indicates that all packets that are currently pending (sent
    /// with `PutPacket` but not yet released) should be released as
    /// well as any pending `End` indications, and that this process
    /// should continue downstream. For example, a decoder that
    /// receives a call to this method on the `StreamSink` it
    /// implements (the docoder’s input), the decoder should release
    /// all unreleased packets and `End` indications previously
    /// received on the input and call `Clear` on its output
    /// `StreamSink`.
    ///
    /// + request `hold_last_frame` whether a video renderer receiving
    ///   the clear signal should hold the last frame (true) or show
    ///   black (false).
    /// + request `completion_fence` an eventpair to be passed along with
    ///   the clear signal and closed when the signal reaches the end of
    ///   end of the pipeline. When a clear operation is forwarded
    ///   downstream in a pipeline, the `completion_fence` or a duplicate
    ///   thereof should be used in the downstream `Clear` calls.
    Clear(resource struct {
        hold_last_frame bool;
        completion_fence zx.handle:EVENTPAIR :optional;
    });
};

/// Describes a packet delivered via `StreamSink`.
type Packet = struct {
    /// Locations of the payload for this packet. The effective
    /// payload comprises all the payload ranges concatenated in
    /// the order they appear in `payload`.
    payload vector<PayloadRange>:MAX_PAYLOAD_RANGES;

    /// Timestamp indicating when this packet should be presented as a
    /// presentation timeline value.
    timestamp PacketTimestamp;

    /// Capture time for this packet as a system monotonic time value.
    /// This field is generally zero, but may be set by capturers
    /// to indicate when this packet was captured.
    capture_timestamp zx.time = 0;

    /// Properties describing packets in a compressed stream. This
    /// value may be provided for a packet in a compressed stream,
    /// and may not be provided for any packet in an uncompressed
    /// stream. If a packet in a compressed stream omits this value,
    /// default compression properties are assumed.
    compression_properties PacketCompressionProperties:optional;

    /// Properties describing packets in an encrypted stream. This
    /// value must be provided for every packet in an encrypted
    /// stream, and may not be provided for any packet in an
    /// unencrypted stream.
    encryption_properties PacketEncryptionProperties:optional;
};

/// Describes a packet payload.
type PayloadRange = struct {
    /// The id of the buffer in which the payload resides.
    buffer_id uint32;

    /// The offset of the payload in the specified buffer.
    offset uint64;

    /// The size in bytes of the payload.
    size uint64;
};

/// Indicates the time of the packet in the presentation timeline.
type PacketTimestamp = flexible union {
    /// Specific timestamp in the presentation timeline.
    1: specified int64;

    /// Indicates the packet should be presented immediately
    /// after the previous packet, if there is a previous
    /// packet. If there is no previous packet, this option
    /// is equivalent to a `specified` value of 0.
    2: unspecified_continuous struct {};

    /// Indicates the packet should be presented as soon as
    /// possible after the previous packet, if there is one,
    /// as soon as possible if not.
    3: unspecified_best_effort struct {};

    // TODO: There’s an argument to be made for another option
    // here, which means “present ASAP, discarding all previous
    // packets.” That would be used for video trick modes like
    // timeline scrubbing.
};

/// Properties accompanying a packet in a compressed stream.
type PacketCompressionProperties = flexible union {
    /// Properties accompanying a packet in a compressed audio
    /// stream. Providing audio properties for a non-audio stream
    /// is an error.
    1: audio AudioPacketCompressionProperties;

    /// Properties accompanying a packet in a compressed video
    /// stream. Providing video properties for a non-video stream
    /// is an error.
    2: video VideoPacketCompressionProperties;
};

/// Properties accompanying a packet in a compressed audio stream.
type AudioPacketCompressionProperties = table {
    /// Indicates how many frames should be dropped from the front of
    /// the packet produced by a decoder from this packet. When this
    /// value is absent, a value of 0 is implied.
    1: front_frames_to_drop uint32;

    /// Indicates how many frames should be dropped from the back of
    /// the packet produced by a decoder from this packet. When this
    /// value is absent, a value of 0 is implied.
    2: back_frames_to_drop uint32;
};

/// Properties accompanying a packet in a compressed video stream.
type VideoPacketCompressionProperties = table {
    /// Flags describing the packet. If this value is omitted, a value
    /// with no flags set is implied.
    1: flags VideoPacketCompressionFlags;
};

/// Flags describing a packet in a compressed video stream.
type VideoPacketCompressionFlags = flexible bits {
    /// Indicates that this access unit can be interpreted without
    /// information from any other packet.
    KEY_FRAME = 0x01;

    /// Indicates that no other access unit requires information
    /// from this access unit in order to be interpreted.
    DROPPABLE = 0x02;

    /// Indicates that this access unit is provided only so that later access units can be
    /// interpreted. A decoder should drop the decompressed frame generated from this
    /// access unit.
    DROP_AFTER_DECODE = 0x04;
};

/// Properties accompanying a packet in an encrypted stream.
type PacketEncryptionProperties = struct {
    /// Indicates whether the packet is encrypted.
    is_encrypted bool;

    /// If specified, overrides the previous key id.
    key_id fuchsia.mediastreams.EncryptionKeyId:optional;

    /// If specified, overrides the previous initialization vector.
    init_vector fuchsia.mediastreams.EncryptionInitVector:optional;

    /// If specified, overrides the previous encryption pattern.
    pattern box<fuchsia.mediastreams.EncryptionPattern>;

    /// Subsamples to decrypt. An empty list indicates whole sample
    /// decryption.
    subsamples vector<fuchsia.mediastreams.EncryptionSubsampleEntry>:MAX_SUBSAMPLE_ENTRIES;
};
