blob: e7b0be9ad997f03fab93c66b68482383bf92834c [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;
// 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.
// TODO(FIDL-609): Default 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.
// TODO(FIDL-609): Default 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.
// TODO(FIDL-609): Default 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.
// TODO(FIDL-609): Default 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.
// TODO(FIDL-609): Default to false.
6: bool require_report_all_detected_errors;
/// If true, require that the returned codec is HW-accelerated.
// TODO(FIDL-609): Default 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.
// 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.
// TODO(FIDL-609): Default to false.
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;
};
/// 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.
// TODO(FIDL-609): Default to false.
2: bool require_hw;
};
enum CodecType {
DECODER = 0;
ENCODER = 1;
};
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 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;
};
// CodecFactory
//
// The purpose of the media::CodecFactory interface is to create media::Codec
// instances.
//
// The interface methods don't attempt to homogenize all codec types, preferring
// to have a separate dedicated message for decoders. TBD whether calls for
// creating encoders will split up audio vs. video encoders, or be combined.
//
// Each create request is self-contained, in the sense that the interface is not
// stateful between create requests.
[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> codecs);
// 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.
//
// TODO(dustingreen): More detail in this comment block.
// 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.
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);
};