blob: 59c1242b46f0b5fa30d71c928e6d7697e07d36f9 [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;
// CreateDecoder_Params
//
// Input parameters for creating a decoder (audio or video).
//
// TODO(dustingreen): Switch this to a FIDL table instead when possible.
struct CreateDecoder_Params {
// Input mime type for a decoder.
//
// The recognized mime types for now:
// audio/aac
// input_details.codec_oob_bytes must be an AudioSpecificConfig() as defined
// by AAC spec.
// audio/aac-adts
// On a temporary basis, input_details.codec_oob_bytes must be an
// AudioSpecificConfig() extracted from the ADTS stream data by the client.
// This is temporary. Later, codec_oob_bytes will be ignored and allowed to
// be null. On a temporary basis, see
// make_AudioSpecificConfig_from_ADTS_header() for some self-contained
// conversion code.
// TODO(dustingreen): fix this up server side and make most of this
// paragraph go away, possibly by also parsing ADTS before it hits OMX
// since the parsing code there doesn't tolerate split ADTS headers.
CodecFormatDetails 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.
bool promise_separate_access_units_on_input = false;
// "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.
bool require_can_stream_bytes_input = false;
// 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.
bool require_can_find_start = false;
// 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.
bool require_can_re_sync = false;
// 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 timstamp_ish values provided on input
// are guaranteed to show up on ouput.
bool require_report_all_detected_errors = false;
// If true, require that the returned codec is HW-accelerated.
bool require_hw = false;
// 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.
bool permit_lack_of_split_header_handling = false;
};
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]
interface 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<Codec> decoder);
// TODO(dustingreen):
// CreateAudioEncoder
// CreateVideoEncoder
// (or combined)
};