blob: 93db6b8b557b919a3b15df6c648e958306b4c94c [file] [log] [blame]
// 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.mediacodec;
using fuchsia.media;
using zx;
// CreateDecoder_Params
//
// Input parameters for creating a decoder (audio or video).
//
/// Whether buffers need to be secure. If not specified, the default is OFF.
///
/// This enum may have additional values added later; code handling this type
/// should be written with this in mind. For example, in C++, having a
/// "default" case in any switch statement on this type will avoid compilation
/// warnings/errors when a new value is added.
//
// Later we can add DYNAMIC, as needed.
enum SecureMemoryMode : uint32 {
// Normal memory. This is the default if a field of this type is not set.
OFF = 0;
// Secure memory.
ON = 1;
};
table CreateDecoder_Params {
/// Input mime type for a decoder.
///
/// The recognized mime types for now:
/// video/h264
/// video/vp9
/// audio/aac
/// input_details.oob_bytes must be an AudioSpecificConfig() as defined
/// by AAC spec.
/// audio/sbc
/// input_details.oob_bytes must be Codec Specific Information Elements
/// for SBC as defined by the A2DP spec.
1: fuchsia.media.FormatDetails input_details;
// The settings below nail down more details.
/// This must be true in order for the client to be permitted to put a
/// timestamp on an input packet, which is in turn required to get any
/// timestamps on any output packets.
///
/// It is always legal to provide separate Access Units (henceforth AUs) to a
/// decoder, but this boolean must be true for a decoder to accept and
/// propagate timestamp values.
///
/// This must be true when creating a video encoder, or the CodecFactory
/// channel will close.
///
/// If not set, defaults to false.
2: bool promise_separate_access_units_on_input;
// "require" fields:
//
// Specifying any of these "require" fields can result in failure to get a
// Codec if there's no suitable codec. None of these correspond to any
// required features of a codec server.
//
// TODO(dustingreen): implement filtering codecs based on these fields.
/// Require that the selected codec be capable of accepting input where
/// AUs are not separated into separate packets.
///
/// This does not imply that the decoder can find the start of the first AU;
/// for that see require_can_find_start. This does not imply that the decoder
/// can re-sync on its own if the stream data is damaged; for that see
/// require_can_re_sync.
///
/// If both promise_separate_access_units_on_input and
/// require_can_stream_bytes_input are true, the CodecFactory channel will
/// close.
///
/// If this is false, the client must feed separate AUs on the fuchsia.ui.input. This
/// must be false for a video encoder, and if true the CodecFactory channel
/// will close.
///
/// Unless a client demands a decoder capable of taking concatenated AUs
/// (require_can_stream_bytes_input true), the client must feed a decoder
/// separate AUs. This means the client cannot have parts of two separate AUs
/// in the same packet, unless require_can_stream_bytes_input is true.
///
/// If not set, defaults to false.
3: bool require_can_stream_bytes_input;
/// A decoder is allowed to be capable of streaming bytes but not capable of
/// searching for the start of the first usable AU. To require both, set both
/// require_can_stream_bytes_input and require_can_find_start. Setting
/// require_can_find_start without require_can_stream_bytes_input is invalid.
///
/// With require_can_stream_bytes_input true but require_can_find_start false,
/// the client must start the first packet with the start of an AU, but can
/// send a stream of bytes after that.
///
/// If not set, defaults to false.
4: bool require_can_find_start;
/// On problematic input data, all decoders are expected to at least be able to
/// close the channel rather than getting stuck in a failed and/or broken
/// state.
///
/// A decoder returned from a request with require_can_re_sync is potentially
/// able to handle damaged input without closing the Codec channel. Such a
/// Codec is encouraged, but not required, to also satisfy requirements of
/// require_report_all_detected_errors.
///
/// If not set, defaults to false.
5: bool require_can_re_sync;
/// Sometimes a client would rather fail an overall use of a decoder than fail
/// to notice data corruption. For such scenarios, the client can specify
/// require_report_all_detected_errors. For any codec returned from a
/// request with require_report_all_detected_errors set, on detection of
/// any input data corruption the codec will report in one or more of these
/// ways:
/// * closing the Codec channel
/// * OnStreamFailed()
/// * error_detected_before
/// * error_detected_during
///
/// If false, a codec may silently skip past corrupted input data.
///
/// No decoder can detect all corruption, because some corruption can look like
/// valid stream data. This requirement is only to request a codec that
/// is written to attempt to detect _and report_ input stream corruption.
///
/// This flag is not intended to be 100% bulletproof. If a client needs robust
/// assurance that _all_ detectable stream corruption is _always_ detected,
/// this flag is not enough of a guarantee to achieve that. Since some stream
/// corruption is inherently non-detectable in any case, such a client should
/// consider using stronger techniques upstream to ensure that corruption can
/// be detected with the needed probability very close to 1.
///
/// This flag being true doesn't imply anything about whether the codec will
/// discard damaged data vs. producing corresponding damaged output. Only that
/// the codec will set error_detected_* bools to true when appropriate.
///
/// Regardless of this setting, not all timestamp_ish values provided on input
/// are guaranteed to show up on output.
///
/// If not set, defaults to false.
6: bool require_report_all_detected_errors;
/// If true, require that the returned codec is HW-accelerated. See also
/// `require_sw`.
///
/// If not set, defaults to false.
7: bool require_hw;
/// permit_lack_of_split_header_handling
///
/// This field is a temporary field that will be going away.
///
/// TODO(dustingreen): Remove this field once we're down to zero codecs with
/// problems handling split headers.
///
/// By default, a Codec instance is required to handle "split headers", meaning
/// that a client is allowed to deliver parts of an AU one byte at a time,
/// including parts near the beginning of the AU, and the codec is required to
/// tolerate and handle that properly. However, unfortunately not all codecs
/// properly support split headers. If a client is willing to permit such a
/// codec to be used, the client can set this to true. Clients are not
/// encouraged to set this, but setting it may be necessary to find a codec for
/// some formats _for now_. If a client sets this to true, the client should
/// deliver data of each AU with many contiguous non-split bytes from the start
/// of each AU. The client is not strictly required to deliver one AU at a
/// time, only to ensure that either all the AU bytes are in a single packet or
/// that many bytes at the start of each AU are in a single packet.
///
/// The specification for how a client should use this and how a client should
/// behave if setting this to true is intentionally vague, because lack of
/// support for header splitting is not ideal, and is expected to be
/// temporary, and all codecs should handle split headers in the long run.
/// The main intent of this field is to avoid giving an innocent client using
/// default value of false here a codec that can't properly handle split
/// headers. This is not an attempt at a mechanism to fully work around a
/// codec that doesn't handle split headers.
///
/// If not set, defaults to false.
//
// TODO(dustingreen): In the near term, wire this up so that SoftAAC2.cpp
// used for ADTS is not selected when this field is false, even if there is
// no other suitable codec. In the long term, fix or work around the header
// handling behavior of SoftAAC2 when used in ADTS mode (and any other
// similar issues in other codecs) and remove this field.
8: bool permit_lack_of_split_header_handling;
/// If set to ON, the decoder must support secure buffers on output, and
/// must reject non-secure buffers on output.
///
/// If set to OFF or not set, the created decoder will reject secure buffers
/// on output by closing the StreamProcessor channel.
///
/// If secure_input_mode ON, secure_output_mode must also be ON.
9: SecureMemoryMode secure_output_mode;
/// If set to ON, the decoder must support secure buffers on input and must
/// reject non-secure buffers on input.
///
/// If set to OFF or not set, the created decoder will reject secure buffers
/// on input by closing the StreamProcessor channel.
///
/// If secure_input_mode ON, secure_output_mode must also be ON.
10: SecureMemoryMode secure_input_mode;
/// If true, require that the returned codec is entirely SW-based, not
/// HW-accelerated (other than possibly using vector CPU instructions).
/// This can be useful for testing purposes or other special scenarios, but
/// is not recommended for performance-sensitive scenarios. Also, some
/// builds may lack a SW-based decoder for some formats. See also
/// `require_hw`.
///
/// If not set, defaults to false.
11: bool require_sw;
};
/// Parameters used to request an encoder.
table CreateEncoder_Params {
/// The format of the uncompressed input data.
///
/// This field should be a raw mime_type (e.g. 'video/raw') and uncompressed
/// format details for the encoder to use when reading buffers.
///
/// To be elibigible an encoder must support the input format.
1: fuchsia.media.FormatDetails input_details;
/// If true, require that the returned codec is HW-accelerated.
///
/// If not set, defaults to false.
2: bool require_hw;
};
enum CodecType {
DECODER = 0;
ENCODER = 1;
};
/// Constrain the mime_type to a size that won't cause problems.
const uint32 CODEC_FACTORY_MAX_MIME_TYPE_LENGTH = 256;
struct CodecDescription {
/// Decoder or encoder.
CodecType codec_type;
/// The mime type of the compressed format. For decoders this is the mime
/// type of the input. For encoders, this is the mime type of the output.
string:CODEC_FACTORY_MAX_MIME_TYPE_LENGTH mime_type;
// TODO(dustingreen): All these fields should be optional.
//
// TODO(dustingreen): Re-evaluate this for encoders.
//
/// For each of these fields, the default is the most-capable setting, but
/// if a codec doesn't support the most-capable behavior, then the codec
/// must override the default.
bool can_stream_bytes_input = true;
bool can_find_start = true;
bool can_re_sync = true;
bool will_report_all_detected_errors = true;
bool is_hw = true;
bool split_header_handling = true;
};
/// More than this many calls to AttachLifetimeTracking()
/// without a Create{X}() call will result in CodecFactory channel closing from
/// the server end.
const uint32 CODEC_FACTORY_LIFETIME_TRACKING_EVENTPAIR_PER_CREATE_MAX = 16;
/// Constrain the length of the codec list.
const uint32 CODEC_FACTORY_CODEC_LIST_SIZE_MAX = 256;
/// CodecFactory
///
/// The purpose of the media::CodecFactory interface is to create
/// media::StreamProcessor instances for decoders and encoders.
///
/// The interface methods don't attempt to homogenize all codec types,
/// preferring to have a separate dedicated message for decoders.
[Discoverable]
protocol CodecFactory {
/// Driver-based local CodecFactory(s) will send this once shortly after the
/// main CodecFactory connects to the driver-local CodecFactory.
///
/// For now, the main CodecFactory will not send this.
///
/// A SW-based local CodecFactory(s) will not send this event.
///
/// Each codec in the list must be separately-described, for clean aggregation.
-> OnCodecList(vector<CodecDescription>:CODEC_FACTORY_CODEC_LIST_SIZE_MAX codecs);
// Requests:
/// CreateDecoder:
///
/// decoder_params - See CreateDecoder_Params comments for required
/// and optional parameters for creating a decoder.
///
/// decoder - a Codec.NewRequest() which will hopefully be connected to
/// a Codec server, or the Codec channel will get closed if no suitable
/// codec can be found. We don't return any additional Codec-specific
/// status here because finding the Codec is allowed to be fully async, so
/// we don't necessarily yet know on return from this method which Codec
/// will be selected, if any.
///
/// Rough sequence to create a decoder:
///
/// factory = ConnectToEnvironmentService(CodecFactory);
/// CreateDecoder_Params params;
/// [fill out params]
/// CreateDecoder(params, decoder_request);
///
/// See use_media_decoder code for more detail.
CreateDecoder(
CreateDecoder_Params decoder_params,
request<fuchsia.media.StreamProcessor> decoder);
/// CreateEncoder:
///
/// encoder_params - See CreateEncoder_Params comments for required
/// and optional parameters for creating a decoder.
///
/// encoder - a Codec.NewRequest() which will hopefully be connected to
/// a Codec server, or the Codec channel will get closed if no suitable
/// codec can be found. We don't return any additional Codec-specific
/// status here because finding the Codec is allowed to be fully async, so
/// we don't necessarily yet know on return from this method which Codec
/// will be selected, if any.
CreateEncoder(CreateEncoder_Params encoder_params,
request<fuchsia.media.StreamProcessor> encoder);
/// AttachLifetimeTracking:
///
/// Attach an eventpair endpoint to the next Create{X}(), so that the
/// codec_end will signal ZX_EVENTPAIR_PEER_CLOSED on the peer of codec_end
/// shortly after the created codec is gone. Multiple eventpair endpoints
/// can be attached per create, with an enforced limit of
/// CODEC_FACTORY_LIFETIME_TRACKING_EVENTPAIR_PER_CREATE_MAX.
///
/// The lifetime signalled by this event is intended to track all resources
/// used by the codec, including sysmem-allocated buffers.
///
/// In the case of server process crashes, or failure of a codec to plumb
/// codec_end to sysmem, ZX_EVENTPAIR_PEER_CLOSED signalled on the peer of
/// codec_end may occur shortly before all resources are freed.
///
/// A maximum of CODEC_FACTORY_LIFETIME_TRACKING_EVENTPAIR_PER_CREATE_MAX
/// calls to AttachLifetimeTracking() are allowed
/// before any Create{X}(). There is no way to cancel an attach short of
/// closing the CodecFactory channel. Closing the client end of the
/// eventpair doesn't subtract from the number of pending attach(es). For
/// this reason, it can be good to only send attach message(s) immediately
/// before the relevant Create{X}(), when it's known by the client that both
/// the attach message(s) and the Create{X}() messages will be sent.
///
/// Closing the client's end doesn't result in any action by the server.
/// If the server listens to events from the client end at all, it is for
/// debug logging only.
///
/// The server intentionally doesn't "trust" any bits signalled by the
/// client. This mechanism intentionally uses only ZX_EVENTPAIR_PEER_CLOSED
/// which can't be triggered early, and is only triggered when all handles
/// to codec_end are closed. No meaning is associated with any of the other
/// signal bits, and clients should functionally ignore any other signal
/// bits on either end of the eventpair or its peer.
///
/// The codec_end may lack ZX_RIGHT_SIGNAL or ZX_RIGHT_SIGNAL_PEER, but must
/// have ZX_RIGHT_DUPLICATE (and must have ZX_RIGHT_TRANSFER to transfer
/// without causing CodecFactory channel failure).
[Transitional = "AttachLifetimeTracking() not yet implemented"]
AttachLifetimeTracking(
zx.handle:EVENTPAIR codec_end);
};