// 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)
};
