blob: 790ae8062f048fd7b1f9162f8fc251a0ae13a340 [file] [log] [blame]
// Copyright 2022 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.video;
using fuchsia.drm;
using fuchsia.media2;
using zx;
/// A packet consumer for cross-process video stream transport, implemented by video consumers
/// and used by video producers.
closed protocol StreamSink {
/// Puts a packet to the sink.
strict PutPacket(resource table {
/// Describes the packet. This field is required.
1: packet Packet;
/// Eventpair closed when the consumer is done with the packet and the buffer region
/// associated with the packet may be reused. Packets may be released in any order. The
/// release fence may be duplicated by the service, so it must be sent with right
/// `ZX_RIGHT_DUPLICATE`. This field is optional.
2: release_fence zx.Handle:EVENTPAIR;
});
/// Starts a new segment. Packets following this request and preceding the next such request
/// are assigned to the segment.
strict StartSegment(table {
/// Identifies the segment. New segment IDs for a given connection must always be strictly
/// increasing. This field is required.
1: segment_id int64;
});
/// Indicates that the end of the stream has been reached. Consumers such as 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. This method is logically scoped to the current segment. A
/// `SetSegment` request and (typically) more packets may follow this request.
strict End();
/// Sent immediately before the producer closes to indicate why the producer is closing the
/// connection. After sending this request, the producer must refrain from sending any more
/// messages and close the connection promptly.
strict WillClose(table {
/// Reason the connection will close.
1: reason fuchsia.media2.ProducerClosedReason;
});
/// Sent immediately before the consumer closes to indicate why the consumer is closing the
/// connection. After sending this event, the consumer must refrain from sending any more
/// messages and close the connection promptly.
strict -> OnWillClose(table {
/// Reason the connection will close.
1: reason fuchsia.media2.ConsumerClosedReason;
});
};
/// An extended packet consumer for cross-process transport of uncompressed video streams
/// that may change dimensions.
closed protocol VariableStreamSink {
compose StreamSink;
/// The provided buffer_collection_id applies to all packets received via `PutPacket` until the
/// next `SetBufferCollection` (if any).
///
/// `SetBufferCollection` will always be sent on a given `VariableStreamSink` connection before
/// the first packet. A new `segment_id` does not imply a new `buffer_collection_id`.
///
/// When a new format needs to be set, a `SetBufferCollection` request must be sent before any
/// `SetFormat` request that applies to packets using buffers of the new collection.
///
/// Redundant `SetBufferCollection` messages are considered a protocol error. Each
/// `SetBufferCollection` must change the current `buffer_collection_id`. If a protocol error
/// is detected, the server should close the `VariableStreamSink` channel.
///
/// A new valid `buffer_collection_id` value is established out-of-band. The
/// `VariableStreamSink` client must not send the `SetBufferCollection` until the
/// `VariableStreamSink` server is already aware of the `buffer_collection_id`. In some
/// scenarios, the new `buffer_collection_id` may be established out-of-band quite a while
/// before usage by any packet; in others, only shortly before usage. Out-of-band establishment
/// of a new `buffer_collection_id` is not a guarantee that any packet will ever use the
/// established `buffer_collection_id`.
///
/// If a not-yet-established `buffer_collection_id` is received via
/// `SetBufferCollection`, the `VariableStreamSink` connection should be closed by the
/// `VariableStreamSink` server.
///
/// The `buffer_collection_id` logically starts at 0 and is incremented for each
/// `buffer_collection_id`. However, not all `buffer_collection_id` values necessarily are
/// established, nor are all `buffer_collection_id` values ever sent in a `SetBufferCollection`
/// message. In other words, gaps must be tolerated. While the ordering of establishment of
/// `buffer_collection_id`s is numerically increasing, the ordering of use of
/// `buffer_collection_id`s via `SetBufferCollection` is not necessarily increasing.
///
/// This message must be sent before the first `PutPacket` message on the connection, and will
/// also be sent before any packet whose `buffer_collection_id` differs from the immediately
/// previous packet's `buffer_collection_id`. A packet's `buffer_collection_id` is implicitly
/// the most-recently-received `buffer_collection_id`, not stored explicitly in the packet. A
/// new `segment_id` does not necessarily imply a new `buffer_collection_id`. If the buffers
/// are still suitable, they can continue to be used.
strict SetBufferCollection(table {
/// The id of the new buffer collection.
1: buffer_collection_id int64;
});
/// Specifies the format of subsequent frames. Only geometry changes are currently supported.
strict SetFormat(table {
/// The new format. The `image_format` field must be populated, and all of the required
/// fields of the image format must be populated. Given that only geometry changes are
/// supported, image format fields `pixel_format`, `pixel_format_modifier`, and
/// `color_space` must remain unchanged with respect to the previously-established format.
1: format Format;
});
/// Notifies the server that the specified buffer will soon be used.
///
/// This message can be sent by the client as soon as the client knows which `buffer_id` of a
/// `buffer_collection_id` will be used for the first time (per `buffer_collection_id`). This
/// can often be sent well in advance of the buffer being filled and ready to be indicated via
/// `PutPacket`, allowing the server to get a significant head start on asking sysmem for the
/// buffer's VMO when the server is participating in incremental sysmem buffer allocation.
///
/// A client is not required to send this message before using a buffer via `PutPacket`, and a
/// server is not required to do anything upon reception of this message. If the client doesn't
/// send this message or the server ignores it, the server must ask sysmem for a VMO
/// corresponding to `buffer_collection_id` and `buffer_id` (if the server hasn't already done
/// so previously) upon reception of `PutPacket` indicating that buffer at the server.
strict PrepareBuffer(table {
/// The buffer collection containing the buffer that will be used.
1: buffer_collection_id int64;
/// The ID of the buffer that will be used.
2: buffer_id int64;
});
/// Notifies that server that the specified buffer will no longer be used.
///
/// The client will not send any subsequent packets which reference this buffer, so the server
/// can drop the corresponding VMO handle as soon as the server no longer needs the VMO for any
/// server-specific purpose.
///
/// Sysmem will recycle the space used by a VMO with zero VMO handles even if not all the
/// buffer collection` channels are closed yet, allowing for incremental deallocation of
/// buffers in a buffer collection as the `VariableStreamSink` moves from one buffer collection
/// to another (typically with larger buffers).
///
/// After all buffers of a buffer collection are decommissioned via `DoneWithBuffer` requests,
/// the client won't send any more messages referring to the buffer collection, and the server
/// can close the server's corresponding buffer collection channel as soon as the server no
/// longer has any use for it.
///
/// A server which intentionally fails if the server receives a second `SetBufferCollection`
/// request may also ignore this message. This is discouraged, but possible and potentially
/// still a useful server for some scenarios (not involving handling of dimension switching
/// that needs larger buffers).
///
/// A server that handles reception of `SetBufferCollection` beyond the first one must also
/// handle this message.
strict DoneWithBuffer(table {
/// The buffer collection containing the buffer that will no longer be used.
1: buffer_collection_id int64;
/// The ID of the buffer that will no longer be used.
2: buffer_id int64;
});
};
/// Describes a packet delivered via `StreamSink` or `VariableStreamSink`.
type Packet = table {
/// Location of the payload for this packet. This field is required.
1: payload fuchsia.media2.PayloadRange;
/// Timestamp indicating when this packet should be presented as a time in the stream
/// timeline. Units vary and are provided when the connection is established. This value is
/// required and must be identical for each packet comprising a given access unit.
2: timestamp int64;
/// Capture time for this packet as a system monotonic time value. This field is optional and
/// may be set by capturers to indicate when this packet was captured.
3: capture_timestamp zx.Time;
/// Flags describing the packet. Omitting this field implies all flags are clear.
4: flags PacketFlags;
/// Describes the encryption applied to this packet. Omitting this field implies the packet is
/// not encrypted.
5: encryption_properties fuchsia.drm.PacketEncryptionProperties;
};
/// Flags describing a packet.
type PacketFlags = flexible bits {
/// Indicates that this access unit can be interpreted without information from any other
/// packet. Each packet in a given access unit must be consistent with respect to this bit.
KEY_FRAME = 0x01;
/// Indicates that no other access unit requires information from this access unit in order to
/// be interpreted. Each packet in a given access unit must be consistent with respect to this
/// bit.
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.
/// Each packet in a given access unit must be consistent with respect to this bit.
DROP_AFTER_DECODE = 0x04;
/// Indicates whether this packet continues the access unit of which it is a part (set) or is
/// the first packet of the access unit (clear).
CONTINUES_ACCESS_UNIT = 0x08;
/// Indicates whether the access unit of which this packet is a part continues with the next
/// packet (set), or this packet is the last packet in the access unit (clear).
ACCESS_UNIT_CONTINUES = 0x10;
/// Indicates whether any parsing / processing errors were detected in data prior to the input
/// data corresponding to this output packet. Not all data corruptions are detectable. When
/// this is set, there may be a discontinuity in packet delivery, in the sense that some prior
/// packet(s) may have been skipped / omitted.
///
/// If the discontinuity is only a timing discontinuity, this flag will not be set solely for
/// that reason, and instead the timestamps (and possibly capture timestamps) will indicate the
/// per-frame timing.
///
/// In transcoding scenarios, this bit is never expected to be set, but if it is, the transcode
/// should be indicated as faulty / incomplete.
///
/// Not all codec implementations will be able to detect errors / detect errors reliably. Some
/// codec implementations may simply close the connection and report an error via the node
/// control channel instead of handling a data corruption, when a corruption is detected at all.
ERROR_DETECTED_BEFORE = 0x20;
/// Indicates whether any parsing / processing errors were detected within the input data
/// directly corresponding to this output packet. Not all data corruptions are detectable.
/// When this flag is set but `ERROR_DETECTED_BEFORE `is not set, no discontinuity in packet
/// delivery has been detected. When this flag is set, the content of this packet is far more
/// likely to be corrupted than when this flag is not set.
///
/// In transcoding scenarios, this bit is never expected to be set, but if it is, the transcode
/// should be indicated as faulty / incomplete.
///
/// Not all codec implementations will be able to detect errors / detect errors reliably. Some
/// codec implementations may simply close the connection and report an error via the node
/// control channel instead of handling a data corruption, when a corruption is detected at all.
ERROR_DETECTED_DURING = 0x40;
};