// 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).
//

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.
    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;
};

/// 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_format;

    /// The desired format of the encoded output data.
    ///
    /// To be eligible an encoder must support the output mime_type and any
    /// compressed format details.
    2: fuchsia.media.FormatDetails output_format;

    /// If true, require that the returned codec is HW-accelerated.
    // TODO(FIDL-609): Default to false.
    3: 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);
};
