/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.hardware.tv.tuner@1.0;

import android.hidl.safe_union@1.0;
import android.hidl.safe_union@1.0::Monostate;

@export
enum Result : int32_t {
    SUCCESS,
    UNAVAILABLE,
    NOT_INITIALIZED,
    INVALID_STATE,
    INVALID_ARGUMENT,
    OUT_OF_MEMORY,
    UNKNOWN_ERROR,
};

/**
 * Frontend ID.
 */
typedef uint32_t FrontendId;

/**
 *  Frontend Types.
 */
@export
enum FrontendType : uint32_t {
    UNDEFINED = 0,
    ANALOG,
    /**
     * Advanced Television Systems Committee (ATSC) Standard A/72.
     */
    ATSC,
    /**
     * Advanced Television Systems Committee (ATSC 3.0) Standard A/300.
     */
    ATSC3,
    /**
     * Digital Video Broadcasting - Cable
     * DVB Cable Frontend Standard ETSI EN 300 468 V1.15.1.
     */
    DVBC,
    /**
     * Digital Video Broadcasting - Satellite
     * DVB Satellite Frontend Standard ETSI EN 300 468 V1.15.1 and
     * ETSI EN 302 307-2 V1.1.1.
     */
    DVBS,
    /**
     * Digital Video Broadcasting - Terrestrial
     * DVB Terrestrial Frontend Standard ETSI EN 300 468 V1.15.1 and
     * ETSI EN 302 755 V1.4.1.
     */
    DVBT,
    /**
     * Integrated Services Digital Broadcasting-Satellite (ISDB-S)
     * ARIB STD-B20 is technical document of ISDB-S.
     */
    ISDBS,
    /**
     * Integrated Services Digital Broadcasting-Satellite (ISDB-S)
     * ARIB STD-B44 is technical document of ISDB-S3.
     */
    ISDBS3,
    /**
     * Integrated Services Digital Broadcasting-Terrestrial (ISDB-T or SBTVD)
     * ABNT NBR 15603 is technical document of ISDB-T.
     */
    ISDBT,
};

/**
 *  Inner Forward Error Correction type as specified in ETSI EN 300 468 V1.15.1
 *  and ETSI EN 302 307-2 V1.1.1.
 */
@export
enum FrontendInnerFec : uint64_t {
    /**
     * Not defined
     */
    FEC_UNDEFINED = 0,
    /**
     * hardware is able to detect and set FEC automatically
     */
    AUTO = 1 << 0,
    /**
     * 1/2 conv. code rate
     */
    FEC_1_2 = 1 << 1,
    /**
     * 1/3 conv. code rate
     */
    FEC_1_3 = 1 << 2,
    /**
     * 1/4 conv. code rate
     */
    FEC_1_4 = 1 << 3,
    /**
     * 1/5 conv. code rate
     */
    FEC_1_5 = 1 << 4,
    /**
     * 2/3 conv. code rate
     */
    FEC_2_3 = 1 << 5,
    /**
     * 2/5 conv. code rate
     */
    FEC_2_5 = 1 << 6,
    /**
     * 2/9 conv. code rate
     */
    FEC_2_9 = 1 << 7,
    /**
     * 3/4 conv. code rate
     */
    FEC_3_4 = 1 << 8,
    /**
     * 3/5 conv. code rate
     */
    FEC_3_5 = 1 << 9,
    /**
     * 4/5 conv. code rate
     */
    FEC_4_5 = 1 << 10,
    /**
     * 4/15 conv. code rate
     */
    FEC_4_15 = 1 << 11,
    /**
     * 5/6 conv. code rate
     */
    FEC_5_6 = 1 << 12,
    /**
     * 5/9 conv. code rate
     */
    FEC_5_9 = 1 << 13,
    /**
     * 6/7 conv. code rate
     */
    FEC_6_7 = 1 << 14,
    /**
     * 7/8 conv. code rate
     */
    FEC_7_8 = 1 << 15,
    /**
     * 7/9 conv. code rate
     */
    FEC_7_9 = 1 << 16,
    /**
     * 7/15 conv. code rate
     */
    FEC_7_15 = 1 << 17,
    /**
     * 8/9 conv. code rate
     */
    FEC_8_9 = 1 << 18,
    /**
     * 8/15 conv. code rate
     */
    FEC_8_15 = 1 << 19,
    /**
     * 9/10 conv. code rate
     */
    FEC_9_10 = 1 << 20,
    /**
     * 9/20 conv. code rate
     */
    FEC_9_20 = 1 << 21,
    /**
     * 11/15 conv. code rate
     */
    FEC_11_15 = 1 << 22,
    /**
     * 11/20 conv. code rate
     */
    FEC_11_20 = 1 << 23,
    /**
     * 11/45 conv. code rate
     */
    FEC_11_45 = 1 << 24,
    /**
     * 13/18 conv. code rate
     */
    FEC_13_18 = 1 << 25,
    /**
     * 13/45 conv. code rate
     */
    FEC_13_45 = 1 << 26,
    /**
     * 14/45 conv. code rate
     */
    FEC_14_45 = 1 << 27,
    /**
     * 23/36 conv. code rate
     */
    FEC_23_36 = 1 << 28,
    /**
     * 25/36 conv. code rate
     */
    FEC_25_36 = 1 << 29,
    /**
     * 26/45 conv. code rate
     */
    FEC_26_45 = 1 << 30,
    /**
     * 28/45 conv. code rate
     */
    FEC_28_45 = 1 << 31,
    /**
     * 29/45 conv. code rate
     */
    FEC_29_45 = 1 << 32,
    /**
     * 31/45 conv. code rate
     */
    FEC_31_45 = 1 << 33,
    /**
     * 32/45 conv. code rate
     */
    FEC_32_45 = 1 << 34,
    /**
     * 77/90 conv. code rate
     */
    FEC_77_90 = 1 << 35,
};

/**
 *  Modulation Type for ATSC.
 */
@export
enum FrontendAtscModulation : uint32_t {
    UNDEFINED = 0,
    /**
     * hardware is able to detect and set modulation automatically
     */
    AUTO = 1 << 0,
    MOD_8VSB = 1 << 2,
    MOD_16VSB = 1 << 3,
};

/**
 *  Signal Settings for an ATSC Frontend.
 */
struct FrontendAtscSettings {
    /**
     * Signal frequency in Hertz
     */
    uint32_t frequency;

    FrontendAtscModulation modulation;
};

/**
 *  Capabilities for ATSC Frontend.
 */
struct FrontendAtscCapabilities {
    /**
     * Modulation capability
     */
    bitfield<FrontendAtscModulation> modulationCap;
};

/**
 *  Modulation Type for ATSC3.
 */
@export
enum FrontendAtsc3Modulation : uint32_t {
    UNDEFINED = 0,
    /**
     * hardware is able to detect and set modulation automatically
     */
    AUTO = 1 << 0,
    MOD_QPSK = 1 << 1,
    MOD_16QAM = 1 << 2,
    MOD_64QAM = 1 << 3,
    MOD_256QAM = 1 << 4,
    MOD_1024QAM = 1 << 5,
    MOD_4096QAM = 1 << 6,
};

/**
 *  Bandwidth for ATSC3.
 */
@export
enum FrontendAtsc3Bandwidth : uint32_t {
    UNDEFINED = 0,
    /**
     * hardware is able to detect and set bandwidth automatically
     */
    AUTO = 1 << 0,
    BANDWIDTH_6MHZ = 1 << 1,
    BANDWIDTH_7MHZ = 1 << 2,
    BANDWIDTH_8MHZ = 1 << 3,
};

/**
 *  Time Interleave Mode for ATSC3.
 */
@export
enum FrontendAtsc3TimeInterleaveMode : uint32_t {
    UNDEFINED = 0,
    /**
     * hardware is able to detect and set TimeInterleaveMode automatically
     */
    AUTO = 1 << 0,
    CTI = 1 << 1,
    HTI = 1 << 2,
};

/**
 *  Code Rate for ATSC3.
 */
@export
enum FrontendAtsc3CodeRate : uint32_t {
    UNDEFINED = 0,
    /**
     * hardware is able to detect and set Coderate automatically
     */
    AUTO = 1 << 0,
    CODERATE_2_15 = 1 << 1,
    CODERATE_3_15 = 1 << 2,
    CODERATE_4_15 = 1 << 3,
    CODERATE_5_15 = 1 << 4,
    CODERATE_6_15 = 1 << 5,
    CODERATE_7_15 = 1 << 6,
    CODERATE_8_15 = 1 << 7,
    CODERATE_9_15 = 1 << 8,
    CODERATE_10_15 = 1 << 9,
    CODERATE_11_15 = 1 << 10,
    CODERATE_12_15 = 1 << 11,
    CODERATE_13_15 = 1 << 12,
};

/**
 *  Forward Error Correction (FEC) for ATSC3.
 */
@export
enum FrontendAtsc3Fec : uint32_t {
    UNDEFINED = 0,
    /**
     * hardware is able to detect and set FEC automatically
     */
    AUTO = 1 << 0,
    BCH_LDPC_16K = 1 << 1,
    BCH_LDPC_64K = 1 << 2,
    CRC_LDPC_16K = 1 << 3,
    CRC_LDPC_64K = 1 << 4,
    LDPC_16K = 1 << 5,
    LDPC_64K = 1 << 6,
};

/**
 *  Demodulator Output Format for an ATSC3 Frontend.
 */
@export
enum FrontendAtsc3DemodOutputFormat : uint8_t {
    /**
     * Dummy. Scan uses this.
     */
    UNDEFINED = 0,
    /**
     * ALP format. Typically used in US region.
     */
    ATSC3_LINKLAYER_PACKET = 1 << 0,
    /**
     * BaseBand packet format. Typically used in Korea region.
     */
    BASEBAND_PACKET = 1 << 1,
};

/**
 *  PLP basis Signal Settings for an ATSC3 Frontend.
 */
struct FrontendAtsc3PlpSettings {
    uint8_t plpId;

    FrontendAtsc3Modulation modulation;

    FrontendAtsc3TimeInterleaveMode interleaveMode;

    FrontendAtsc3CodeRate codeRate;

    FrontendAtsc3Fec fec;
};

/**
 *  Signal Settings for an ATSC3 Frontend.
 */
struct FrontendAtsc3Settings {
    /**
     * Signal frequency in Hertz
     */
    uint32_t frequency;

    /**
     * Bandwidth of tuning band.
     */
    FrontendAtsc3Bandwidth bandwidth;

    FrontendAtsc3DemodOutputFormat demodOutputFormat;

    vec<FrontendAtsc3PlpSettings> plpSettings;
};

/**
 *  Capabilities for ATSC3 Frontend.
 */
struct FrontendAtsc3Capabilities {
    /**
     * Bandwidth capability
     */
    bitfield<FrontendAtsc3Bandwidth> bandwidthCap;

    /**
     * Modulation capability
     */
    bitfield<FrontendAtsc3Modulation> modulationCap;

    /**
     * TimeInterleaveMode capability
     */
    bitfield<FrontendAtsc3TimeInterleaveMode> timeInterleaveModeCap;

    /**
     * CodeRate capability
     */
    bitfield<FrontendAtsc3CodeRate> codeRateCap;

    /**
     * FEC capability
     */
    bitfield<FrontendAtsc3Fec> fecCap;

    /**
     * Demodulator Output Format capability
     */
    bitfield<FrontendAtsc3DemodOutputFormat> demodOutputFormatCap;
};

/**
 *  Modulation Type for DVBS.
 */
@export
enum FrontendDvbsModulation : int32_t {
    UNDEFINED = 0,
    /**
     * hardware is able to detect and set Modulation automatically
     */
    AUTO = 1 << 0,
    MOD_QPSK = 1 << 1,
    MOD_8PSK = 1 << 2,
    MOD_16QAM = 1 << 3,
    MOD_16PSK = 1 << 4,
    MOD_32PSK = 1 << 5,
    MOD_ACM = 1 << 6,
    MOD_8APSK = 1 << 7,
    MOD_16APSK = 1 << 8,
    MOD_32APSK = 1 << 9,
    MOD_64APSK = 1 << 10,
    MOD_128APSK = 1 << 11,
    MOD_256APSK = 1 << 12,
    /**
     * Reserved for Proprietary modulation
     */
    MOD_RESERVED = 1 << 13,
};

/**
 *  Roll Off value for DVBS.
 */
@export
enum FrontendDvbsRolloff : uint32_t {
    UNDEFINED,
    ROLLOFF_0_35,
    ROLLOFF_0_25,
    ROLLOFF_0_20,
    ROLLOFF_0_15,
    ROLLOFF_0_10,
    ROLLOFF_0_5,
};

/**
 *  Pilot mode for DVBS.
 */
@export
enum FrontendDvbsPilot : uint32_t {
    UNDEFINED,
    ON,
    OFF,
    AUTO,
};

/**
 *  Code Rate for DVBS.
 */
struct FrontendDvbsCodeRate {
    FrontendInnerFec fec;

    bool isLinear;

    /**
     * true if enable short frame
     */
    bool isShortFrames;

    /**
     * bits number in 1000 symbol. 0 if use the default.
     */
    uint32_t bitsPer1000Symbol;
};

/**
 *  Sub standards in DVBS.
 */
@export
enum FrontendDvbsStandard : uint8_t {
    AUTO = 1 << 0,
    S = 1 << 1,
    S2 = 1 << 2,
    S2X = 1 << 3,
};

/**
 *   VCM mode in DVBS.
 */
@export
enum FrontendDvbsVcmMode : uint32_t {
    UNDEFINED,
    AUTO,
    MANUAL,
};

/**
 *  Signal Settings for an DVBS Frontend.
 */
struct FrontendDvbsSettings {
    /**
     * Signal frequency in Hertz
     */
    uint32_t frequency;

    FrontendDvbsModulation modulation;

    FrontendDvbsCodeRate coderate;

    /**
     * Symbols per second
     */
    uint32_t symbolRate;

    FrontendDvbsRolloff rolloff;

    FrontendDvbsPilot pilot;

    uint32_t inputStreamId;

    FrontendDvbsStandard standard;

    FrontendDvbsVcmMode vcmMode;
};

/**
 *  Capabilities for DVBS Frontend.
 */
struct FrontendDvbsCapabilities {
    bitfield<FrontendDvbsModulation> modulationCap;

    bitfield<FrontendInnerFec> innerfecCap;

    bitfield<FrontendDvbsStandard> standard;
};

/**
 *  Modulation Type for DVBC.
 */
@export
enum FrontendDvbcModulation : uint32_t {
    UNDEFINED = 0,
    /**
     * hardware is able to detect and set Modulation automatically
     */
    AUTO = 1 << 0,
    MOD_16QAM = 1 << 1,
    MOD_32QAM = 1 << 2,
    MOD_64QAM = 1 << 3,
    MOD_128QAM = 1 << 4,
    MOD_256QAM = 1 << 5,
};

/**
 *  Outer Forward Error Correction (FEC) Type for DVBC.
 */
@export
enum FrontendDvbcOuterFec : uint32_t {
    UNDEFINED = 0,
    OUTER_FEC_NONE,
    OUTER_FEC_RS,
};

/**
 *   Annex Type for DVBC.
 */
@export
enum FrontendDvbcAnnex : uint8_t {
    UNDEFINED = 0,
    A = 1 << 0,
    B = 1 << 1,
    C = 1 << 2,
};

/**
 *   Spectral Inversion Type for DVBC.
 */
@export
enum FrontendDvbcSpectralInversion : uint32_t {
    UNDEFINED,
    NORMAL,
    INVERTED,
};

/**
 *  Signal Settings for an DVBC Frontend.
 */
struct FrontendDvbcSettings {
    /**
     * Signal frequency in Hertz
     */
    uint32_t frequency;

    FrontendDvbcModulation modulation;

    FrontendInnerFec fec;

    /**
     * Symbols per second
     */
    uint32_t symbolRate;

    FrontendDvbcOuterFec outerFec;

    FrontendDvbcAnnex annex;

    FrontendDvbcSpectralInversion spectralInversion;
};

/**
 *  Capabilities for DVBC Frontend.
 */
struct FrontendDvbcCapabilities {
    bitfield<FrontendDvbcModulation> modulationCap;

    bitfield<FrontendInnerFec> fecCap;

    bitfield<FrontendDvbcAnnex> annexCap;
};

/**
 *  Bandwidth Type for DVBT.
 */
@export
enum FrontendDvbtBandwidth : uint32_t {
    UNDEFINED = 0,
    /**
     * hardware is able to detect and set Bandwidth automatically
     */
    AUTO = 1 << 0,
    BANDWIDTH_8MHZ = 1 << 1,
    BANDWIDTH_7MHZ = 1 << 2,
    BANDWIDTH_6MHZ = 1 << 3,
    BANDWIDTH_5MHZ = 1 << 4,
    BANDWIDTH_1_7MHZ = 1 << 5,
    BANDWIDTH_10MHZ = 1 << 6,
};

/**
 *  Constellation Type for DVBT.
 */
@export
enum FrontendDvbtConstellation : uint32_t {
    UNDEFINED = 0,
    /**
     * hardware is able to detect and set Constellation automatically
     */
    AUTO = 1 << 0,
    CONSTELLATION_QPSK = 1 << 1,
    CONSTELLATION_16QAM = 1 << 2,
    CONSTELLATION_64QAM = 1 << 3,
    CONSTELLATION_256QAM = 1 << 4,
};

/**
 *  Hierarchy Type for DVBT.
 */
@export
enum FrontendDvbtHierarchy : uint32_t {
    UNDEFINED = 0,
    /**
     * hardware is able to detect and set Hierarchy automatically
     */
    AUTO = 1 << 0,
    HIERARCHY_NON_NATIVE = 1 << 1,
    HIERARCHY_1_NATIVE = 1 << 2,
    HIERARCHY_2_NATIVE = 1 << 3,
    HIERARCHY_4_NATIVE = 1 << 4,
    HIERARCHY_NON_INDEPTH = 1 << 5,
    HIERARCHY_1_INDEPTH = 1 << 6,
    HIERARCHY_2_INDEPTH = 1 << 7,
    HIERARCHY_4_INDEPTH = 1 << 8,
};

/**
 *  Hierarchy Type for DVBT.
 */
@export
enum FrontendDvbtCoderate : uint32_t {
    UNDEFINED = 0,
    /**
     * hardware is able to detect and set Hierarchy automatically
     */
    AUTO = 1 << 0,
    CODERATE_1_2 = 1 << 1,
    CODERATE_2_3 = 1 << 2,
    CODERATE_3_4 = 1 << 3,
    CODERATE_5_6 = 1 << 4,
    CODERATE_7_8 = 1 << 5,
    CODERATE_3_5 = 1 << 6,
    CODERATE_4_5 = 1 << 7,
    CODERATE_6_7 = 1 << 8,
    CODERATE_8_9 = 1 << 9,
};

/**
 *  Guard Interval Type for DVBT.
 */
@export
enum FrontendDvbtGuardInterval : uint32_t {
    UNDEFINED = 0,
    /**
     * hardware is able to detect and set Guard Interval automatically
     */
    AUTO = 1 << 0,
    INTERVAL_1_32 = 1 << 1,
    INTERVAL_1_16 = 1 << 2,
    INTERVAL_1_8 = 1 << 3,
    INTERVAL_1_4 = 1 << 4,
    INTERVAL_1_128 = 1 << 5,
    INTERVAL_19_128 = 1 << 6,
    INTERVAL_19_256 = 1 << 7,
};

/**
 *  Transmission Mode for DVBT.
 */
@export
enum FrontendDvbtTransmissionMode : uint32_t {
    UNDEFINED = 0,
    /**
     * hardware is able to detect and set Transmission Mode automatically
     */
    AUTO = 1 << 0,
    MODE_2K = 1 << 1,
    MODE_8K = 1 << 2,
    MODE_4K = 1 << 3,
    MODE_1K = 1 << 4,
    MODE_16K = 1 << 5,
    MODE_32K = 1 << 6,
};

/**
 *   Physical Layer Pipe (PLP) Mode for DVBT.
 */
@export
enum FrontendDvbtPlpMode : uint32_t {
    UNDEFINED,
    AUTO,
    MANUAL,
};

/**
 *  Sub standards in DVBT.
 */
@export
enum FrontendDvbtStandard : uint8_t {
    AUTO = 1 << 0,
    T = 1 << 1,
    T2 = 1 << 2,
};

/**
 *  Signal Settings for DVBT Frontend.
 */
struct FrontendDvbtSettings {
    /**
     * Signal frequency in Hertz
     */
    uint32_t frequency;

    FrontendDvbtTransmissionMode transmissionMode;

    FrontendDvbtBandwidth bandwidth;

    FrontendDvbtConstellation constellation;

    FrontendDvbtHierarchy hierarchy;

    /**
     * Code Rate for High Priority level
     */
    FrontendDvbtCoderate hpCoderate;

    /**
     * Code Rate for Low Priority level
     */
    FrontendDvbtCoderate lpCoderate;

    FrontendDvbtGuardInterval guardInterval;

    bool isHighPriority;

    FrontendDvbtStandard standard;

    bool isMiso;

    FrontendDvbtPlpMode plpMode;

    /**
     * Physical Layer Pipe (PLP) Id
     */
    uint8_t plpId;

    /**
     * Group Id for Physical Layer Pipe (PLP)
     */
    uint8_t plpGroupId;
};

/**
 *  Capabilities for DVBT Frontend.
 */
struct FrontendDvbtCapabilities {
    bitfield<FrontendDvbtTransmissionMode> transmissionModeCap;

    bitfield<FrontendDvbtBandwidth> bandwidthCap;

    bitfield<FrontendDvbtConstellation> constellationCap;

    bitfield<FrontendDvbtCoderate> coderateCap;

    bitfield<FrontendDvbtHierarchy> hierarchyCap;

    bitfield<FrontendDvbtGuardInterval> guardIntervalCap;

    bool isT2Supported;

    bool isMisoSupported;
};

/**
 *  Roll Off Type for ISDBS.
 */
@export
enum FrontendIsdbsRolloff : uint32_t {
    UNDEFINED,
    ROLLOFF_0_35,
};

/**
 *  Modulation Type for ISDBS.
 */
@export
enum FrontendIsdbsModulation : uint32_t {
    UNDEFINED = 0,
    /**
     * hardware is able to detect and set Modulation automatically
     */
    AUTO = 1 << 0,
    MOD_BPSK = 1 << 1,
    MOD_QPSK = 1 << 2,
    MOD_TC8PSK = 1 << 3,
};

/**
 *  Code Rate Type for ISDBS.
 */
@export
enum FrontendIsdbsCoderate : uint32_t {
    UNDEFINED = 0,
    /**
     * hardware is able to detect and set Code Rate automatically
     */
    AUTO = 1 << 0,
    CODERATE_1_2 = 1 << 1,
    CODERATE_2_3 = 1 << 2,
    CODERATE_3_4 = 1 << 3,
    CODERATE_5_6 = 1 << 4,
    CODERATE_7_8 = 1 << 5,
};

/**
 *  Stream Id Type for ISDBS.
 */
@export
enum FrontendIsdbsStreamIdType : uint32_t {
    STREAM_ID,
    RELATIVE_STREAM_NUMBER,
};

/**
 *  Signal Settings for ISDBS Frontend.
 */
struct FrontendIsdbsSettings {
    /**
     * Signal frequency in Hertz
     */
    uint32_t frequency;

    uint16_t streamId;

    FrontendIsdbsStreamIdType streamIdType;

    FrontendIsdbsModulation modulation;

    FrontendIsdbsCoderate coderate;

    /**
     * Symbols per second
     */
    uint32_t symbolRate;

    FrontendIsdbsRolloff rolloff;
};

/**
 *  Capabilities for ISDBS Frontend.
 */
struct FrontendIsdbsCapabilities {
    bitfield<FrontendIsdbsModulation> modulationCap;

    bitfield<FrontendIsdbsCoderate> coderateCap;
};

/**
 *  Roll of Type for ISDBS3.
 */
@export
enum FrontendIsdbs3Rolloff : uint32_t {
    UNDEFINED,
    ROLLOFF_0_03,
};

/**
 *  Modulaltion Type for ISDBS3.
 */
@export
enum FrontendIsdbs3Modulation : uint32_t {
    UNDEFINED = 0,
    /**
     * hardware is able to detect and set Modulation automatically
     */
    AUTO = 1 << 0,
    MOD_BPSK = 1 << 1,
    MOD_QPSK = 1 << 2,
    MOD_8PSK = 1 << 3,
    MOD_16APSK = 1 << 4,
    MOD_32APSK = 1 << 5,
};

/**
 *  Code Rate Type for ISDBS3.
 */
@export
enum FrontendIsdbs3Coderate : uint32_t {
    UNDEFINED = 0,
    /**
     * hardware is able to detect and set Code Rate automatically
     */
    AUTO = 1 << 0,
    CODERATE_1_3 = 1 << 1,
    CODERATE_2_5 = 1 << 2,
    CODERATE_1_2 = 1 << 3,
    CODERATE_3_5 = 1 << 4,
    CODERATE_2_3 = 1 << 5,
    CODERATE_3_4 = 1 << 6,
    CODERATE_7_9 = 1 << 7,
    CODERATE_4_5 = 1 << 8,
    CODERATE_5_6 = 1 << 9,
    CODERATE_7_8 = 1 << 10,
    CODERATE_9_10 = 1 << 11,
};

/**
 *  Signal Settings for ISDBS3 Frontend.
 */
struct FrontendIsdbs3Settings {
    /**
     * Signal frequency in Hertz
     */
    uint32_t frequency;

    uint16_t streamId;

    FrontendIsdbsStreamIdType streamIdType;

    FrontendIsdbs3Modulation modulation;

    FrontendIsdbs3Coderate coderate;

    /**
     * Symbols per second
     */
    uint32_t symbolRate;

    FrontendIsdbs3Rolloff rolloff;
};

/**
 *  Capabilities for ISDBS3 Frontend.
 */
struct FrontendIsdbs3Capabilities {
    bitfield<FrontendIsdbs3Modulation> modulationCap;

    bitfield<FrontendIsdbs3Coderate> coderateCap;
};

/**
 *   Mode for ISDBT.
 */
@export
enum FrontendIsdbtMode : uint32_t {
    UNDEFINED = 0,
    /**
     * hardware is able to detect and set Mode automatically
     */
    AUTO = 1 << 0,
    MODE_1 = 1 << 1,
    MODE_2 = 1 << 2,
    MODE_3 = 1 << 3,
};

/**
 *   Bandwidth for ISDBT.
 */
@export
enum FrontendIsdbtBandwidth : uint32_t {
    UNDEFINED = 0,
    /**
     * hardware is able to detect and set Bandwidth automatically
     */
    AUTO = 1 << 0,
    BANDWIDTH_8MHZ = 1 << 1,
    BANDWIDTH_7MHZ = 1 << 2,
    BANDWIDTH_6MHZ = 1 << 3,
};

/**
 *   Modulation for ISDBT.
 */
@export
enum FrontendIsdbtModulation : uint32_t {
    UNDEFINED = 0,
    /**
     * hardware is able to detect and set Modulation automatically
     */
    AUTO = 1 << 0,
    MOD_DQPSK = 1 << 1,
    MOD_QPSK = 1 << 2,
    MOD_16QAM = 1 << 3,
    MOD_64QAM = 1 << 4,
};

typedef FrontendDvbtCoderate FrontendIsdbtCoderate;

typedef FrontendDvbtGuardInterval FrontendIsdbtGuardInterval;

/**
 *  Signal Settings for ISDBT Frontend.
 */
struct FrontendIsdbtSettings {
    /**
     * Signal frequency in Hertz
     */
    uint32_t frequency;

    FrontendIsdbtModulation modulation;

    FrontendIsdbtBandwidth bandwidth;

    FrontendIsdbtMode mode;

    FrontendIsdbtCoderate coderate;

    FrontendIsdbtGuardInterval guardInterval;

    uint32_t serviceAreaId;
};

/**
 *  Capabilities for ISDBT Frontend.
 */
struct FrontendIsdbtCapabilities {
    bitfield<FrontendIsdbtMode> modeCap;

    bitfield<FrontendIsdbtBandwidth> bandwidthCap;

    bitfield<FrontendIsdbtModulation> modulationCap;

    bitfield<FrontendIsdbtCoderate> coderateCap;

    bitfield<FrontendIsdbtGuardInterval> guardIntervalCap;
};

/**
 *   Signal Type for Analog Frontend.
 */
@export
enum FrontendAnalogType : uint32_t {
    UNDEFINED = 0,
    AUTO = 1 << 0,
    PAL = 1 << 1,
    PAL_M = 1 << 2,
    PAL_N = 1 << 3,
    PAL_60 = 1 << 4,
    NTSC = 1 << 5,
    NTSC_443 = 1 << 6,
    SECAM = 1 << 7,
};

/**
 *   Standard Interchange Format (SIF) for Analog Frontend.
 */
@export
enum FrontendAnalogSifStandard : uint32_t {
    UNDEFINED = 0,
    AUTO = 1 << 0,
    BG = 1 << 1,
    BG_A2 = 1 << 2,
    BG_NICAM = 1 << 3,
    I = 1 << 4,
    DK = 1 << 5,
    DK1_A2 = 1 << 6,
    DK2_A2 = 1 << 7,
    DK3_A2 = 1 << 8,
    DK_NICAM = 1 << 9,
    L = 1 << 10,
    M = 1 << 11,
    M_BTSC = 1 << 12,
    M_A2 = 1 << 13,
    M_EIAJ = 1 << 14,
    I_NICAM = 1 << 15,
    L_NICAM = 1 << 16,
    L_PRIME = 1 << 17,
};

/**
 *  Signal Settings for Analog Frontend.
 */
struct FrontendAnalogSettings {
    /**
     * Signal frequency in Hertz
     */
    uint32_t frequency;

    FrontendAnalogType type;

    FrontendAnalogSifStandard sifStandard;
};

/**
 *  Capabilities for Analog Frontend.
 */
struct FrontendAnalogCapabilities {
    bitfield<FrontendAnalogType> typeCap;

    bitfield<FrontendAnalogSifStandard> sifStandardCap;
};

/**
 *  Signal Settings for Frontend.
 */
safe_union FrontendSettings {
    FrontendAnalogSettings analog;

    FrontendAtscSettings atsc;

    FrontendAtsc3Settings atsc3;

    FrontendDvbsSettings dvbs;

    FrontendDvbcSettings dvbc;

    FrontendDvbtSettings dvbt;

    FrontendIsdbsSettings isdbs;

    FrontendIsdbs3Settings isdbs3;

    FrontendIsdbtSettings isdbt;
};

/**
 *  Scan type for Frontend.
 */
@export
enum FrontendScanType : uint32_t {
    SCAN_UNDEFINED = 0,
    SCAN_AUTO = 1 << 0,
    SCAN_BLIND = 1 << 1,
};

/**
 *  Scan Message Type for Frontend.
 */
@export
enum FrontendScanMessageType : uint32_t {
    /**
     * Scan locked the signal.
     */
    LOCKED,
    /**
     * Scan stopped.
     */
    END,
    /**
     * Scan progress report.
     */
    PROGRESS_PERCENT,
    /**
     * Locked frequency report.
     */
    FREQUENCY,
    /**
     * Locked symbol rate.
     */
    SYMBOL_RATE,
    /**
     * Locked HIERARCHY for DVBT2 frontend.
     */
    HIERARCHY,
    ANALOG_TYPE,
    /**
     * Locked Plp Ids for DVBT2 frontend.
     */
    PLP_IDS,
    /**
     * Locked group Ids for DVBT2 frontend.
     */
    GROUP_IDS,
    /**
     * Stream Ids.
     */
    INPUT_STREAM_IDS,
    /**
     * Locked signal standard.
     */
    STANDARD,
    /**
     * PLP status in a tuned frequency band for ATSC3 frontend.
     */
    ATSC3_PLP_INFO,
};

/**
 *  ATSC3.0 PLP information for scan
 */
struct FrontendScanAtsc3PlpInfo {
    uint8_t plpId;

    bool bLlsFlag;
};

/**
 *  Scan Message for Frontend.
 */
safe_union FrontendScanMessage {
    bool isLocked;

    bool isEnd;

    /**
     * scan progress percent (0..100)
     */
    uint8_t progressPercent;

    /**
     * Signal frequencies in Hertz
     */
    vec<uint32_t> frequencies;

    /**
     * Symbols per second
     */
    vec<uint32_t> symbolRates;

    FrontendDvbtHierarchy hierarchy;

    FrontendAnalogType analogType;

    vec<uint8_t> plpIds;

    vec<uint8_t> groupIds;

    vec<uint16_t> inputStreamIds;

    safe_union Standard {
        FrontendDvbsStandard sStd;

        FrontendDvbtStandard tStd;

        FrontendAnalogSifStandard sifStd;
    } std;

    /**
     * A list of PLP status in a tuned frequency band for ATSC3 frontend.
     */
    vec<FrontendScanAtsc3PlpInfo> atsc3PlpInfos;
};

/**
 * Frontend Event Type.
 */
@export
enum FrontendEventType : uint32_t {
    /**
     * The frontend has locked to the signal specified by the tune method.
     */
    LOCKED,
    /**
     * The frontend is unable to lock to the signal specified by the tune method.
     */
    NO_SIGNAL,
    /**
     * The frontend has lost the lock to the signal specified by the tune method.
     */
    LOST_LOCK,
};

/**
 * Frontend Status Type.
 */
@export
enum FrontendStatusType : uint32_t {
    /**
     * Lock status for Demod.
     */
    DEMOD_LOCK,
    /**
     * Signal to Noise Ratio.
     */
    SNR,
    /**
     * Bit Error Ratio.
     */
    BER,
    /**
     * Packages Error Ratio.
     */
    PER,
    /**
     * Bit Error Ratio before FEC.
     */
    PRE_BER,
    /**
     * Signal Quality (0..100). Good data over total data in percent can be
     * used as a way to present Signal Quality.
     */
    SIGNAL_QUALITY,
    /**
     * Signal Strength.
     */
    SIGNAL_STRENGTH,
    /**
     * Symbol Rate.
     */
    SYMBOL_RATE,
    /**
     * Forward Error Correction Type.
     */
    FEC,
    /**
     * Modulation Type.
     */
    MODULATION,
    /**
     * Spectral Inversion Type.
     */
    SPECTRAL,
    /**
     * LNB Voltage.
     */
    LNB_VOLTAGE,
    /**
     * Physical Layer Pipe ID.
     */
    PLP_ID,
    /**
     * Status for Emergency Warning Broadcasting System.
     */
    EWBS,
    /**
     * Automatic Gain Control.
     */
    AGC,
    /**
     * Low Noise Amplifier.
     */
    LNA,
    /**
     * Error status by layer.
     */
    LAYER_ERROR,
    /**
     * Moduration Error Ratio.
     */
    MER,
    /**
     * Difference between tuning frequency and actual locked frequency.
     */
    FREQ_OFFSET,
    /**
     * Hierarchy for DVBT.
     */
    HIERARCHY,
    /**
     * Lock status for RF.
     */
    RF_LOCK,
    /**
     * PLP information in a frequency band for ATSC3.0 frontend.
     */
    ATSC3_PLP_INFO,
};

/**
 * Status for each tuning PLPs
 */
struct FrontendStatusAtsc3PlpInfo {
    /**
     * PLP Id value.
     */
    uint8_t plpId;

    /**
     * Demod Lock/Unlock status of this particular PLP.
     */
    bool isLocked;

    /**
     * Uncorrectable Error Counts (UEC) of this particular PLP since last tune operation.
     */
    uint32_t uec;
};

/**
 * Modulation Type for Frontend's status.
 */
safe_union FrontendModulationStatus {
    FrontendDvbcModulation dvbc;

    FrontendDvbsModulation dvbs;

    FrontendIsdbsModulation isdbs;

    FrontendIsdbs3Modulation isdbs3;

    FrontendIsdbtModulation isdbt;
};

/**
 *  The status for Frontend.
 */
safe_union FrontendStatus {
    /**
     * Lock status for Demod in True/False.
     */
    bool isDemodLocked;

    /**
     * SNR value measured by 0.001 dB.
     */
    int32_t snr;

    /**
     * The number of error bit per 1 billion bits.
     */
    uint32_t ber;

    /**
     * The number of error package per 1 billion packages.
     */
    uint32_t per;

    /**
     * The number of error bit per 1 billion bits before FEC.
     */
    uint32_t preBer;

    /**
     * Signal Quality in percent.
     */
    uint32_t signalQuality;

    /**
     * Signal Strength measured by 0.001 dBm.
     */
    int32_t signalStrength;

    /**
     * Symbols per second
     */
    uint32_t symbolRate;

    FrontendInnerFec innerFec;

    FrontendModulationStatus modulation;

    FrontendDvbcSpectralInversion inversion;

    LnbVoltage lnbVoltage;

    uint8_t plpId;

    bool isEWBS;

    /**
     * AGC value is normalized from 0 to 255.
     */
    uint8_t agc;

    bool isLnaOn;

    vec<bool> isLayerError;

    /**
     * MER value measured by 0.001 dB
     */
    int32_t mer;

    /**
     * Frequency difference in Hertz.
     */
    int32_t freqOffset;

    FrontendDvbtHierarchy hierarchy;

    bool isRfLocked;

    /**
     * A list of PLP status for tuned PLPs for ATSC3 frontend.
     */
    vec<FrontendStatusAtsc3PlpInfo> plpInfo;
};

/**
 *  Information for the Frontend.
 */
struct FrontendInfo {
    FrontendType type;

    /**
     * Frequency in Hertz
     */
    uint32_t minFrequency;

    /**
     * Frequency in Hertz
     */
    uint32_t maxFrequency;

    /**
     * Minimum symbols per second
     */
    uint32_t minSymbolRate;

    /**
     * Maximum symbols per second
     */
    uint32_t maxSymbolRate;

    /**
     * Range in Hertz
     */
    uint32_t acquireRange;

    /**
     * Frontends are assigned with the same exclusiveGroupId if they can't
     * function at same time. For instance, they share same hardware module.
     */
    uint32_t exclusiveGroupId;

    /**
     * A list of supported status types which client can inquiry
     */
    vec<FrontendStatusType> statusCaps;

    safe_union FrontendCapabilities {
        FrontendAnalogCapabilities analogCaps;

        FrontendAtscCapabilities atscCaps;

        FrontendAtsc3Capabilities atsc3Caps;

        FrontendDvbsCapabilities dvbsCaps;

        FrontendDvbcCapabilities dvbcCaps;

        FrontendDvbtCapabilities dvbtCaps;

        FrontendIsdbsCapabilities isdbsCaps;

        FrontendIsdbs3Capabilities isdbs3Caps;

        FrontendIsdbtCapabilities isdbtCaps;
    } frontendCaps;
};

/*
 * Low-Noise Block downconverter (LNB) ID is used to associate with a hardware
 * LNB module.
 */
typedef uint32_t LnbId;

/**
 *  Power Voltage Type for LNB.
 */
@export
enum LnbVoltage : uint32_t {
    NONE,
    VOLTAGE_5V,
    VOLTAGE_11V,
    VOLTAGE_12V,
    VOLTAGE_13V,
    VOLTAGE_14V,
    VOLTAGE_15V,
    VOLTAGE_18V,
    VOLTAGE_19V,
};

/**
 *  Tone Type for LNB.
 */
@export
enum LnbTone : int32_t {
    NONE,
    CONTINUOUS,
};

/**
 *  The Position of LNB.
 */
@export
enum LnbPosition : int32_t {
    UNDEFINED,
    POSITION_A,
    POSITION_B,
};

/**
 * Lnb Event Type.
 */
@export
enum LnbEventType : uint32_t {
    DISEQC_RX_OVERFLOW,
    /**
     * If LNB detect that outgoing Diseqc message isn't delivered on time.
     */
    DISEQC_RX_TIMEOUT,
    /**
     * If LNB detect that the incoming Diseqc message has parity error.
     */
    DISEQC_RX_PARITY_ERROR,
    /**
     * If LNB detect that the LNB is overload.
     */
    LNB_OVERLOAD,
};

/* Demux ID is used to associate with a hardware demux resource. */
typedef uint32_t DemuxId;

/**
 * Filter Main Type specifies the protocol that the filter use to extract data
 * from input stream.
 */
@export
enum DemuxFilterMainType : uint32_t {
    /**
     * Transport Stream according to ISO/IEC 13818-1.
     */
    TS = 1 << 0,
    /**
     * MPEG Media Transport Protocol according to ISO/IEC 23008-1.
     */
    MMTP = 1 << 1,
    /**
     * Internet Protocol.
     */
    IP = 1 << 2,
    /**
     * Type Length Value according to ITU-R BT.1869.
     */
    TLV = 1 << 3,
    /**
     * ATSC Link-Layer Protocol according to A/330 ATSC3.0.
     */
    ALP = 1 << 4,
};

/**
 * TS Filter Type according to ISO/IEC 13818-1
 */
@export
enum DemuxTsFilterType : uint32_t {
    UNDEFINED,
    /**
     * A filter to filter Section data out from input stream, and queue the
     * data to the filter's FMQ (Fast Message Queue).
     */
    SECTION,
    /**
     * A filter to filter Packetized Elementary Stream data out from input
     * stream, and queue the data to the filter's FMQ.
     */
    PES,
    /**
     * A filter to filter a Transport Stream out from input stream, and queue
     * the data to the filter's FMQ.
     */
    TS,
    /**
     * A filter to filter Audio data out from input stream, and send Audio's
     * Metadata to client through onFilterEvent.
     */
    AUDIO,
    /**
     * A filter to filter Video data out from input stream, and send Video's
     * Metadata to client through onFilterEvent.
     */
    VIDEO,
    /**
     * A filter to set PCR (Program Clock Reference) channel from input stream.
     */
    PCR,
    /**
     * A filter to filter data out from input stream, and queue the data to the
     * buffer of the record.
     */
    RECORD,
    /**
     * A filter to filter out Timed External Media Information (TEMI) according
     * to ISO/IEC 13818-1:2013/ DAM 6 from input stream, and send TEMI event to
     * client through onFilterEvent.
     */
    TEMI,
};

/**
 * MMTP Filter Type according to ISO/IEC 23008-1
 */
@export
enum DemuxMmtpFilterType : uint32_t {
    UNDEFINED,
    /**
     * A filter to filter signaling data out from input stream, and queue the
     * data to the filter's FMQ (Fast Message Queue).
     */
    SECTION,
    /**
     * A filter to filter MFU (Media fragment unit) out from input stream, and
     * queue the data to the filter's FMQ.
     */
    PES,
    /**
     * A filter to filter a MMTP stream out from input stream, and queue the
     * data to the filter's FMQ.
     */
    MMTP,
    /**
     * A filter to filter Audio data out from input stream, and send Audio's
     * Metadata to client through onFilterEvent.
     */
    AUDIO,
    /**
     * A filter to filter Video data out from input stream, and send Video's
     * Metadata to client through onFilterEvent.
     */
    VIDEO,
    /**
     * A filter to filter data out from input stream, and queue the data to the
     * buffer of the record.
     */
    RECORD,
    /**
     * A filter to filter application data out from input stream, and queue the
     * data to the filter's FMQ.
     */
    DOWNLOAD,
};

/**
 * IP Filter Type.
 */
@export
enum DemuxIpFilterType : uint32_t {
    UNDEFINED,
    /**
     * A filter to filter section data out from input stream, and queue the
     * data to the filter's FMQ (Fast Message Queue).
     */
    SECTION,
    /**
     * A filter to set NTP (Network Time Procotol) channel from input stream.
     */
    NTP,
    /**
     * A filter to strip out IP message header and queue the data to the
     * filter's FMQ.
     */
    IP_PAYLOAD,
    /**
     * A filter to filter a IP stream out from input stream. The output can be
     * either upper stream of another filter or queued to the filter's FMQ.
     */
    IP,
    /**
     * A filter to strip out IP message header and be a data source of another
     * filter.
     */
    PAYLOAD_THROUGH,
};

/**
 * TLV Filter Type according to ITU-R BT.1869.
 */
@export
enum DemuxTlvFilterType : uint32_t {
    UNDEFINED,
    /**
     * A filter to filter signaling data out from input stream, and queue the
     * data to the filter's FMQ (Fast Message Queue).
     */
    SECTION,
    /**
     * A filter to filter a TLV stream out from input stream. The output can be
     * either upper stream of another filter or queued to the filter's FMQ.
     */
    TLV,
    /**
     * A filter to strip out TLV message header and be a data source of another
     * filter.
     */
    PAYLOAD_THROUGH,
};

/**
 * ALP Filter Type according to A/330 ATSC3.0.
 */
@export
enum DemuxAlpFilterType : uint32_t {
    UNDEFINED,
    /**
     * A filter to filter signaling data out from input stream, and queue the
     * data to the filter's FMQ (Fast Message Queue).
     */
    SECTION,
    /**
     * A filter to set PTP (Precision Time Protocol) channel from input stream.
     */
    PTP,
    /**
     * A filter to strip out ALP message header and be a data source of another
     * filter.
     */
    PAYLOAD_THROUGH,
};

/**
 * Demux Filter Type.
 */
struct DemuxFilterType {
    DemuxFilterMainType mainType;

    safe_union DemuxFilterSubType {
        DemuxTsFilterType tsFilterType;

        DemuxMmtpFilterType mmtpFilterType;

        DemuxIpFilterType ipFilterType;

        DemuxTlvFilterType tlvFilterType;

        DemuxAlpFilterType alpFilterType;
    } subType;
};

/* Packet ID is used to specify packets in transport stream. */
typedef uint16_t DemuxTpid;

/* Packet ID is used to specify packets in MMTP */
typedef uint16_t DemuxMmtpPid;

/**
 * Demux Packet ID.
 */
safe_union DemuxPid {
    DemuxTpid tPid;

    DemuxMmtpPid mmtpPid;
};

@export
enum Constant : uint32_t {
    /**
     * An invalid packet ID in transport stream according to ISO/IEC 13818-1.
     */
    INVALID_TS_PID = 0xFFFF,
    /**
     * An invalid Stream ID.
     */
    INVALID_STREAM_ID = 0xFFFF,
    /**
     * An invalid Filter ID.
     */
    INVALID_FILTER_ID = 0xFFFFFFFF,
    /**
     * An invalid AV sync hardware ID.
     */
    INVALID_AV_SYNC_ID = 0xFFFFFFFF,
};

/**
 * A status of data in the filter's buffer.
 */
@export
enum DemuxFilterStatus : uint8_t {
    /**
     * The data in the filter buffer is ready to be read.
     */
    DATA_READY = 1 << 0,
    /**
     * The available data amount in the filter buffer is at low level which is
     * set to 25 percent by default.
     */
    LOW_WATER = 1 << 1,
    /**
     * The available data amount in the filter buffer is at high level which is
     * set to 75 percent by default.
     */
    HIGH_WATER = 1 << 2,
    /**
     * The data in the filter buffer is full and newly filtered data is being
     * discarded.
     */
    OVERFLOW = 1 << 3,
};

/**
 * Indexes can be tagged through TS (Transport Stream) header.
 */
@export
enum DemuxTsIndex : uint32_t {
    FIRST_PACKET = 1 << 0,
    PAYLOAD_UNIT_START_INDICATOR = 1 << 1,
    CHANGE_TO_NOT_SCRAMBLED = 1 << 2,
    CHANGE_TO_EVEN_SCRAMBLED = 1 << 3,
    CHANGE_TO_ODD_SCRAMBLED = 1 << 4,
    DISCONTINUITY_INDICATOR = 1 << 5,
    RANDOM_ACCESS_INDICATOR = 1 << 6,
    PRIORITY_INDICATOR = 1 << 7,
    PCR_FLAG = 1 << 8,
    OPCR_FLAG = 1 << 9,
    SPLICING_POINT_FLAG = 1 << 10,
    PRIVATE_DATA = 1 << 11,
    ADAPTATION_EXTENSION_FLAG = 1 << 12,
};

/**
 * Indexes can be tagged by Start Code in PES (Packetized Elementary Stream)
 * according to ISO/IEC 13818-1.
 */
@export
enum DemuxScIndex : uint32_t {
    /**
     * Start Code is for a new I Frame
     */
    I_FRAME = 1 << 0,
    /**
     * Start Code is for a new P Frame
     */
    P_FRAME = 1 << 1,
    /**
     * Start Code is for a new B Frame
     */
    B_FRAME = 1 << 2,
    /**
     * Start Code is for a new Sequence
     */
    SEQUENCE = 1 << 3,
};

/**
 * Indexes can be tagged by NAL unit group in HEVC
 * according to ISO/IEC 23008-2.
 */
@export
enum DemuxScHevcIndex : uint32_t {
    SPS = 1 << 0,
    AUD = 1 << 1,
    SLICE_CE_BLA_W_LP = 1 << 2,
    SLICE_BLA_W_RADL = 1 << 3,
    SLICE_BLA_N_LP = 1 << 4,
    SLICE_IDR_W_RADL = 1 << 5,
    SLICE_IDR_N_LP = 1 << 6,
    SLICE_TRAIL_CRA = 1 << 7,
};

/**
 * Start Code Index type to be used in the filter for record
 */
@export
enum DemuxRecordScIndexType : uint32_t {
    /**
     * Don't use SC index
     */
    NONE,
    /**
     * Use Start Code index
     */
    SC,
    /**
     * Use Start Code index for HEVC
     */
    SC_HEVC,
};

/**
 *  Filter Settings for Record data.
 */
struct DemuxFilterRecordSettings {
    bitfield<DemuxTsIndex> tsIndexMask;

    DemuxRecordScIndexType scIndexType;

    safe_union ScIndexMask {

        bitfield<DemuxScIndex> sc;

        bitfield<DemuxScHevcIndex> scHevc;
    } scIndexMask;
};

/**
 *  Bits Settings for Section Filter.
 */
struct DemuxFilterSectionBits {
    /**
     * The bytes are configured for Section Filter
     */
    vec<uint8_t> filter;

    /**
     * Active bits in the configured bytes to be used for filtering
     */
    vec<uint8_t> mask;

    /**
     * Do positive match at the bit position of the configured bytes when the
     * bit at same position of the mode is 0.
     * Do negative match at the bit position of the configured bytes when the
     * bit at same position of the mode is 1.
     */
    vec<uint8_t> mode;
};

/**
 *  Filter Settings for Section data according to ISO/IEC 13818-1.
 */
struct DemuxFilterSectionSettings {
    safe_union Condition {
        DemuxFilterSectionBits sectionBits;

        struct TableInfo {
            /**
             * Table ID for Section Filter
             */
            uint16_t tableId;

            /**
             * Version number for Section Filter
             */
            uint16_t version;
        } tableInfo;
    } condition;

    /**
     * true if the filter checks CRC and discards data with wrong CRC
     */
    bool isCheckCrc;

    /**
     * true if the filter repeats the data with the same version
     */
    bool isRepeat;

    /**
     * true if the filter send onFilterStatus instead of onFilterEvent.
     */
    bool isRaw;
};

typedef uint16_t DemuxStreamId;

/**
 *  Filter Settings for a PES Data.
 */
struct DemuxFilterPesDataSettings {
    DemuxStreamId streamId;

    /**
     * true if the filter send onFilterStatus instead of onFilterEvent.
     */
    bool isRaw;
};

/**
 *  Filter Settings for a Video and Audio.
 */
struct DemuxFilterAvSettings {
    /**
     * true if the filter output goes to decoder directly in pass through mode.
     */
    bool isPassthrough;
};

/**
 *  Filter Settings for a Download.
 */
struct DemuxFilterDownloadSettings {
    uint32_t downloadId;
};

/**
 *  IP Settings for a IP filter.
 */
struct DemuxIpAddress {
    safe_union SrcIpAddress {
        /**
         * 0.0.0.0 is invalid. should be ignored.
         */
        uint8_t[4] v4;

        /**
         * 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 is invalid. should be ignored.
         */
        uint8_t[16] v6;
    } srcIpAddress;

    safe_union DstIpAddress {
        /**
         * 0.0.0.0 is invalid. should be ignored.
         */
        uint8_t[4] v4;

        /**
         * 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 is invalid. should be ignored.
         */
        uint8_t[16] v6;
    } dstIpAddress;

    /**
     * 0 is invalid. should be ignored.
     */
    uint16_t srcPort;

    /**
     * 0 is invalid. should be ignored.
     */
    uint16_t dstPort;
};

/**
 *  Filter Settings for a TS filter.
 */
struct DemuxTsFilterSettings {
    DemuxTpid tpid;

    safe_union FilterSettings {
        /**
         * Not additional parameters. it's used by PCR, TS, TEMI subtype
         * filters.
         */
        Monostate noinit;

        DemuxFilterSectionSettings section;

        DemuxFilterAvSettings av;

        DemuxFilterPesDataSettings pesData;

        DemuxFilterRecordSettings record;
    } filterSettings;
};

/**
 *  Filter Settings for a MMTP filter.
 */
struct DemuxMmtpFilterSettings {
    DemuxMmtpPid mmtpPid;

    safe_union FilterSettings {
        /**
         * Not additional parameters. it's used by MMTP subtype filters.
         */
        Monostate noinit;

        DemuxFilterSectionSettings section;

        DemuxFilterAvSettings av;

        DemuxFilterPesDataSettings pesData;

        DemuxFilterRecordSettings record;

        DemuxFilterDownloadSettings download;
    } filterSettings;
};

/**
 *  Filter Settings for a IP filter.
 */
struct DemuxIpFilterSettings {
    DemuxIpAddress ipAddr;

    safe_union FilterSettings {
        /**
         * Not additional parameters. it's used by NTP, IP_PAYLOAD,
         * PAYLOAD_THROUGH subtype filters.
         */
        Monostate noinit;

        DemuxFilterSectionSettings section;

        /**
         * true if the data from IP subtype go to next filter directly
         */
        bool bPassthrough;
    } filterSettings;
};

/**
 *  Filter Settings for a TLV filter.
 */
struct DemuxTlvFilterSettings {
    uint8_t packetType;

    /**
     * true if the filtered data is commpressed ip packet
     */
    bool isCompressedIpPacket;

    safe_union FilterSettings {
        /**
         * Not additional parameters. it's used by PAYLOAD_THROUGH subtype
         * filters.
         */
        Monostate noinit;

        DemuxFilterSectionSettings section;

        /**
         * true if the data from TLV subtype go to next filter directly
         */
        bool bPassthrough;
    } filterSettings;
};

/**
 * ALP Length Type
 */
@export
enum DemuxAlpLengthType : uint8_t {
    UNDEFINED = 0,
    /**
     * Length does NOT include additional header. Used in US region.
     */
    WITHOUT_ADDITIONAL_HEADER,
    /**
     * Length includes additional header. Used in Korea region.
     */
    WITH_ADDITIONAL_HEADER,
};

/**
 *  Filter Settings for a ALP filter.
 */
struct DemuxAlpFilterSettings {
    /**
     * 0: IpV4, 2:Compressed Ip, 4:Signaling.
     */
    uint8_t packetType;

    DemuxAlpLengthType lengthType;

    safe_union FilterSettings {
        /**
         * Not additional parameters. it's used by PTP, PAYLOAD_THROUGH subtype
         * filters.
         */
        Monostate noinit;

        DemuxFilterSectionSettings section;
    } filterSettings;
};

/**
 *  Filter Settings.
 */
safe_union DemuxFilterSettings {
    DemuxTsFilterSettings ts;

    DemuxMmtpFilterSettings mmtp;

    DemuxIpFilterSettings ip;

    DemuxTlvFilterSettings tlv;

    DemuxAlpFilterSettings alp;
};

/**
 * The bits of EventFlag in FMQ (Fast message queue) are used by client to
 * notify HAL the status change.
 */
@export
enum DemuxQueueNotifyBits : uint32_t {
    /**
     * client writes data and notify HAL the data is ready.
     */
    DATA_READY = 1 << 0,
    /**
     * client reads data and notify HAL the data is consumed.
     */
    DATA_CONSUMED = 1 << 1,
};

/**
 *  Filter Event for Section Filter.
 */
struct DemuxFilterSectionEvent {
    /**
     * Table ID of filtered data
     */
    uint16_t tableId;

    /**
     * Version number of filtered data
     */
    uint16_t version;

    /**
     * Section number of filtered data
     */
    uint16_t sectionNum;

    /**
     * Data size in bytes of filtered data
     */
    uint16_t dataLength;
};

/**
 *  Extra Meta Data from AD (Audio Descriptor) according to
 *  ETSI TS 101 154 V2.1.1.
 */
struct AudioExtraMetaData {
    uint8_t adFade;

    uint8_t adPan;

    uint8_t versionTextTag;

    uint8_t adGainCenter;

    uint8_t adGainFront;

    uint8_t adGainSurround;
};

/**
 *  Filter Event for Audio or Video Filter.
 */
struct DemuxFilterMediaEvent {
    DemuxStreamId streamId;

    /**
     * true if PTS is present in PES header.
     */
    bool isPtsPresent;

    /**
     * Presentation Time Stamp for audio or video frame. It based on 90KHz has
     * the same format as PTS (Presentation Time Stamp).
     */
    uint64_t pts;

    /**
     * Data size in bytes of audio or video frame
     */
    uint32_t dataLength;

    /**
     *  The offset in the memory block which is shared among multiple
     *  MediaEvents.
     */
    uint32_t offset;

    /**
     * A handle associated to the memory where audio or video data stays.
     */
    handle avMemory;

    /**
     * True if the avMemory is in secure area, and isn't mappable.
     */
    bool isSecureMemory;

    /**
     * An Id is used by HAL to provide additional information for AV data.
     * For secure audio, it's the audio handle used by Audio Track.
     */
    uint64_t avDataId;

    /**
     * MPU sequence number of filtered data (only for MMTP)
     */
    uint32_t mpuSequenceNumber;

    bool isPesPrivateData;

    safe_union ExtraMetaData {
        /**
         * Not additional parameters. it's used for video.
         */
        Monostate noinit;

        AudioExtraMetaData audio;
    } extraMetaData;
};

/**
 *  Filter Event for PES data.
 */
struct DemuxFilterPesEvent {
    DemuxStreamId streamId;

    /**
     * Data size in bytes of PES data
     */
    uint16_t dataLength;

    /**
     * MPU sequence number of filtered data (only for MMTP)
     */
    uint32_t mpuSequenceNumber;
};

/**
 *  Filter Event for TS Record data.
 */
struct DemuxFilterTsRecordEvent {
    DemuxPid pid;

    bitfield<DemuxTsIndex> tsIndexMask;

    /**
     * Indexes of record output
     */
    safe_union ScIndexMask {

        bitfield<DemuxScIndex> sc;

        bitfield<DemuxScHevcIndex> scHevc;
    } scIndexMask;

    /**
     * Byte number from beginning of the filter's output
     */
    uint64_t byteNumber;
};

/**
 *  Filter Event for Timed External Media Information (TEMI) data.
 */
struct DemuxFilterTemiEvent {
    /**
     * Presentation Time Stamp for audio or video frame. It based on 90KHz has
     * the same format as PTS (Presentation Time Stamp) in ISO/IEC 13818-1.
     */
    uint64_t pts;

    /**
     * TEMI Descriptor Tag
     */
    uint8_t descrTag;

    /**
     * TEMI Descriptor
     */
    vec<uint8_t> descrData;
};

/**
 *  Filter Event for MMTP Record data.
 */
struct DemuxFilterMmtpRecordEvent {
    bitfield<DemuxScHevcIndex> scHevcIndexMask;

    /**
     * Byte number from beginning of the filter's output
     */
    uint64_t byteNumber;
};

/**
 *  Filter Event for Download data.
 */
struct DemuxFilterDownloadEvent {
    uint32_t itemId;

    /**
     * MPU sequence number of filtered data (only for MMTP)
     */
    uint32_t mpuSequenceNumber;

    uint32_t itemFragmentIndex;

    uint32_t lastItemFragmentIndex;

    /**
     * Data size in bytes of filtered data
     */
    uint16_t dataLength;
};

/**
 *  Filter Event for IP payload data.
 */
struct DemuxFilterIpPayloadEvent {
    /**
     * Data size in bytes of IP data
     */
    uint16_t dataLength;
};

/**
 * Filter Event.
 */
struct DemuxFilterEvent {
    safe_union Event {
        DemuxFilterSectionEvent section;

        DemuxFilterMediaEvent media;

        DemuxFilterPesEvent pes;

        DemuxFilterTsRecordEvent tsRecord;

        DemuxFilterMmtpRecordEvent mmtpRecord;

        DemuxFilterDownloadEvent download;

        DemuxFilterIpPayloadEvent ipPayload;

        DemuxFilterTemiEvent temi;
    };

    /**
     * An array of events
     */
    vec<Event> events;
};

typedef uint32_t AvSyncHwId;

typedef vec<uint8_t> TunerKeyToken;

/**
 * A data format in demux's output or input according to ISO/IEC 13818-1.
 */
@export
enum DataFormat : uint32_t {
    /**
     * Data is Transport Stream.
     */
    TS,
    /**
     * Data is Packetized Elementary Stream.
     */
    PES,
    /**
     * Data is Elementary Stream.
     */
    ES,
    /**
     * Data is TLV (type-length-value) Stream for JP SHV
     */
    SHV_TLV,
};

typedef DemuxFilterStatus RecordStatus;

/**
 *  The Settings for the record in DVR.
 */
struct RecordSettings {
    /**
     * Register for interested status events so that the HAL can send these
     * status events back to client.
     */
    bitfield<RecordStatus> statusMask;

    /**
     * Unconsumed data size in bytes in the record. The HAL uses it to trigger
     * OutputStatus::LOW_WATER.
     */
    uint32_t lowThreshold;

    /**
     * Unconsumed data size in bytes in the record. The HAL uses it to trigger
     * OutputStatus::High_WATER.
     */
    uint32_t highThreshold;

    /**
     * The data format in the record.
     */
    DataFormat dataFormat;

    /**
     * The packet size in bytes in the record.
     */
    uint8_t packetSize;
};

/**
 * A status of the playback in DVR.
 */
@export
enum PlaybackStatus : uint32_t {
    /**
     * The space of the demux's playback is empty.
     */
    SPACE_EMPTY = 1 << 0,
    /**
     * The spece of the demux's playback is almost empty.
     */
    SPACE_ALMOST_EMPTY = 1 << 1,
    /**
     * The space of the demux's playback is almost full.
     */
    SPACE_ALMOST_FULL = 1 << 2,
    /**
     * The space of the demux's playback is full.
     */
    SPACE_FULL = 1 << 3,
};

/**
 * The Setting for the playback in DVR.
 */
struct PlaybackSettings {
    /**
     * Register for interested status events so that the HAL can send these
     * status events back to client.
     */
    bitfield<PlaybackStatus> statusMask;

    /**
     * Unused space size in bytes in the playback. The HAL uses it to trigger
     * InputStatus::SPACE_ALMOST_EMPTY.
     */
    uint32_t lowThreshold;

    /**
     * Unused space size in bytes in the playback. The HAL uses it to trigger
     * InputStatus::SPACE_ALMOST_FULL.
     */
    uint32_t highThreshold;

    /**
     * The data format in the playback.
     */
    DataFormat dataFormat;

    /**
     * The packet size in bytes in the playback.
     */
    uint8_t packetSize;
};

/**
 * The type of DVR.
 */
@export
enum DvrType : uint8_t {
    RECORD,
    PLAYBACK,
};

/**
 * The Setting for DVR.
 */
safe_union DvrSettings {
    RecordSettings record;

    PlaybackSettings playback;
};

/**
 *  Capabilities for Demux.
 */
struct DemuxCapabilities {
    /**
     * The number of Demux to be supported.
     */
    uint32_t numDemux;

    /**
     * The number of record to be supported.
     */
    uint32_t numRecord;

    /**
     * The number of playback to be supported.
     */
    uint32_t numPlayback;

    /**
     * The number of TS Filter to be supported.
     */
    uint32_t numTsFilter;

    /**
     * The number of Section Filter to be supported.
     */
    uint32_t numSectionFilter;

    /**
     * The number of Audio Filter to be supported.
     */
    uint32_t numAudioFilter;

    /**
     * The number of Video Filter to be supported.
     */
    uint32_t numVideoFilter;

    /**
     * The number of PES Filter to be supported.
     */
    uint32_t numPesFilter;

    /**
     * The number of PCR Filter to be supported.
     */
    uint32_t numPcrFilter;

    /**
     * The maximum number of bytes is supported in the mask of Section Filter.
     */
    uint32_t numBytesInSectionFilter;

    bitfield<DemuxFilterMainType> filterCaps;

    /**
     * The array has same elements as DemuxFilterMainType. linkCaps[i] presents
     * filter's capability as soource for the ith type in DemuxFilterMainType.
     * The jth bit of linkCaps[i] is 1 if the output of ith type filter can be
     * data source for the filter type j.
     */
    vec<bitfield<DemuxFilterMainType>> linkCaps;

    bool bTimeFilter;
};
