/*
 * Copyright (c) 2021, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 3-Clause Clear License
 * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
 * License was not distributed with this source code in the LICENSE file, you
 * can obtain it at aomedia.org/license/software-license/bsd-3-c-c/.  If the
 * Alliance for Open Media Patent License 1.0 was not distributed with this
 * source code in the PATENTS file, you can obtain it at
 * aomedia.org/license/patent-license/.
 */

#ifndef AVM_AV2_COMMON_ENUMS_H_
#define AVM_AV2_COMMON_ENUMS_H_

#include "config/avm_config.h"

#include "avm/avm_codec.h"
#include "avm/avm_integer.h"
#include "avm_ports/mem.h"
#include "avm/avm_frame_buffer.h"

#ifdef __cplusplus
extern "C" {
#endif

/*! @file */

/*!\cond */

#undef MAX_SB_SIZE

#define MAX_PR_NUM 16
#define MAX_DR_STACK_SIZE 4
#define MAX_DR_PR_NUM 2

#define MAX_SEQ_NUM 16

// Macros related to joint shell signaling
#define FIRST_SHELL_CLASS 8
#define SECOND_SHELL_CLASS 8
// Macros related to wedge angle signaling
#define WEDGE_QUADS 4
#define QUAD_WEDGE_ANGLES 5
// Macros related to luma and chroma intra mode signaling
#define LUMA_INTRA_MODE_INDEX_COUNT 8
#define LUMA_INTRA_MODE_OFFSET_COUNT 6
#define CHROMA_INTRA_MODE_INDEX_COUNT 8
// Macro related to EOB position token signaling
#define EOB_PT_INDEX_COUNT 8
// Macros related Inter tx type signaling
#define INTER_TX_TYPE_INDEX_COUNT 8
#define INTER_TX_TYPE_OFFSET1_COUNT 8
#define INTER_TX_TYPE_OFFSET2_COUNT 4
#define INTER_TX_TYPE_SIGNALING_SETS 2
#define TX_EXT_32_CTXS 2

#define FGM_ID_BITS 3
#define MAX_FGM_NUM (1 << FGM_ID_BITS)

#define NUM_CTX_IS_JOINT 2
#define NUM_OPTIONS_IS_JOINT 2
#define NUM_CTX_NON_JOINT_TYPE INTER_MODE_CONTEXTS
#define NUM_OPTIONS_NON_JOINT_TYPE 5
#define NUM_CTX_JOINT_TYPE 1
#define NUM_OPTIONS_JOINT_TYPE 2

// maximum warp bound boxes.
#define MAX_WARP_BD_SIZE (1 << (8 - 3))
#define MAX_WARP_BD_SQ (MAX_WARP_BD_SIZE * MAX_WARP_BD_SIZE)

#define SUBBLK_REF_EXT_LINES 2

#define DMVR_SEARCH_EXT_LINES 2

#define WARP_STATS_BUFFER_SIZE \
  (MAX_WARP_REF_CANDIDATES * NUM_WARP_PRECISION_MODES)

#define AVG_CDF_WEIGHT_PRIMARY 7
#define AVG_CDF_WEIGHT_NON_PRIMARY 1

#define USE_TUNED_ADST4 1
#define USE_TUNED_ADST8 1
#define USE_TUNED_ADST16 1

#define NUM_REF_SAM_CFL 8

#define DEFAULT_IMP_MSK_WT 0  // default implict masked blending weight

#define BAWP_MAX_REF_NUMB 16
#if CONFIG_PARAKIT_COLLECT_DATA
// @ParaKit: add enum variables to indiciate context groups
enum { EOB_FLAG_CDF16, EOB_FLAG_CDF32, MAX_NUM_CTX_GROUPS };
#endif

/*WEDGE_0 is defined in the three o'clock direciton, the angles are defined in
 * the anticlockwise.*/
enum {
  WEDGE_0,
  WEDGE_14,
  WEDGE_27,
  WEDGE_45,
  WEDGE_63,
  WEDGE_90,
  WEDGE_117,
  WEDGE_135,
  WEDGE_153,
  WEDGE_166,
  WEDGE_180,
  WEDGE_194,
  WEDGE_207,
  WEDGE_225,
  WEDGE_243,
  WEDGE_270,
  WEDGE_297,
  WEDGE_315,
  WEDGE_333,
  WEDGE_346,
  WEDGE_ANGLES
} UENUM1BYTE(WedgeDirectionType);

#define H_WEDGE_ANGLES 10
#define NUM_WEDGE_DIST 4
#define MAX_WEDGE_TYPES 68
#define WEDGE_BLD_LUT_SIZE 128

#define WARP_CU_BANK 1
#define REFINEMV_SUBBLOCK_WIDTH 16
#define REFINEMV_SUBBLOCK_HEIGHT 16

#define IBP_WEIGHT_SIZE_LOG2 4
#define IBP_WEIGHT_SIZE (1 << IBP_WEIGHT_SIZE_LOG2)

// Supported scale modes for JOINT_NEWMV
#define JOINT_NEWMV_SCALE_FACTOR_CNT 5
// Supoorted scale modes for JOINT_AMVDNEWMV
#define JOINT_AMVD_SCALE_FACTOR_CNT 3

// Max superblock size
#define MAX_SB_SIZE_LOG2 8
#define MAX_SB_SIZE (1 << MAX_SB_SIZE_LOG2)
#define MAX_SB_SQUARE (MAX_SB_SIZE * MAX_SB_SIZE)
#define BLOCK_128_MI_SIZE_LOG2 5

// Cross-Component Sample Offset (CCSO)
#define CCSO_BLK_SIZE MAX_SB_SIZE_LOG2
#define CCSO_PADDING_SIZE 5
#define CCSO_BAND_NUM 64
#define CCSO_NUM_COMPONENTS 3

#define CFL_MHCCP_SWITCH_NUM 2
#define MHCCP_MODE_NUM 3
#define MHCCP_CONTEXT_GROUP_SIZE 4
// 2 lines of the luma buffer, and 1 line for the chroma buffer
#define LINE_NUM 1
#define MHCCP_NUM_PARAMS 3
#define MHCCP_WINDOW_SIZE 6
#define MHCCP_MAX_REF_SAMPLES \
  (2 * MHCCP_WINDOW_SIZE * (2 * MAX_SB_SIZE + MHCCP_WINDOW_SIZE))
#define MHCCP_DECIM_BITS 16
#define MHCCP_DECIM_ROUND (1 << (MHCCP_DECIM_BITS - 1))

// Min superblock size
#define MIN_SB_SIZE_LOG2 6

// Pixels per Mode Info (MI) unit
#define MI_SIZE_LOG2 2
#define MI_SIZE (1 << MI_SIZE_LOG2)

// 1/8 pels per Mode Info (MI) unit
#define MI_SUBPEL_SIZE_LOG2 (MI_SIZE_LOG2 + 3)

// MI-units per max superblock (MI Block - MIB)
#define MAX_MIB_SIZE_LOG2 (MAX_SB_SIZE_LOG2 - MI_SIZE_LOG2)
#define MAX_MIB_SIZE (1 << MAX_MIB_SIZE_LOG2)

#define MAX_MIB_SQUARE (MAX_MIB_SIZE * MAX_MIB_SIZE)

#if CONFIG_INSPECTION
// MI-units per min superblock
#define MIN_MIB_SIZE_LOG2 (MIN_SB_SIZE_LOG2 - MI_SIZE_LOG2)
#endif  // CONFIG_INSPECTION

// Mask to extract MI offset within max MIB
#define MAX_MIB_MASK (MAX_MIB_SIZE - 1)

// The largest block size where we need to construct chroma blocks separately
// from luma blocks is 64x32. With the four way partition, we can get 64x4
// block sizes. So we only need to track results for 16 mi units.
#define MAX_MI_LUMA_SIZE_FOR_SUB_8 (64 >> MI_SIZE_LOG2)
#define SUB_8_BITMASK_T uint16_t
#define SUB_8_BITMASK_SIZE (16)
#define SUB_8_BITMASK_ON (UINT16_MAX)

// Maximum number of tile rows and tile columns
#define MAX_TILE_ROWS 64
#define MAX_TILE_COLS 64

#define MI_SIZE_64X64 (64 >> MI_SIZE_LOG2)
#define MI_SIZE_128X128 (128 >> MI_SIZE_LOG2)
#define MI_SIZE_256X256 (256 >> MI_SIZE_LOG2)

#define MAX_PALETTE_SQUARE (64 * 64)
// Maximum number of colors in a palette.
#define PALETTE_MAX_SIZE 8
// Minimum number of colors in a palette.
#define PALETTE_MIN_SIZE 2

#define FRAME_OFFSET_BITS 5
#define MAX_FRAME_DISTANCE ((1 << FRAME_OFFSET_BITS) - 1)

// Multiple reference line selection for intra prediction
#define MRL_LINE_NUMBER 4
#define FIRST_MODE_COUNT 13
#define SECOND_MODE_COUNT 16
#define Y_MODE_CONTEXTS 3
#define INTRA_MODE_SETS 4
#define NON_DIRECTIONAL_MODES_COUNT 5
#define UV_MODE_CONTEXTS 2
#define CFL_CONTEXTS 3

// Intra Secondary Transform
// - STX_TYPES: number of IST types (including none) to be signaled before
//   signaling the IST set index. STX_TYPES-1 is the number of IST kernels
//   within each IST set
// - IST_SET_SIZE: number of IST sets for 4x4 DCT_DCT, 4x4 ADST_ADST, and 8x8
//   DCT_DCT
// - IST_REDUCED_SET_SIZE: number of IST sets for 8x8 ADST_ADST
// - IST_4x4_SET_SIZE: number of all 4x4 IST sets (DCT_DCT + ADST_ADST)
// - IST_8x8_SET_SIZE: number of all 8x8 IST sets (DCT_DCT + ADST_ADST)
#define STX_TYPES 4
#define STX_PRED_CTXS 2
#define IST_SET_SIZE 7
#define IST_REDUCED_SET_SIZE 4
#define IST_4x4_SET_SIZE (IST_SET_SIZE + IST_SET_SIZE)
#define IST_8x8_SET_SIZE (IST_SET_SIZE + IST_REDUCED_SET_SIZE)

// - Width: dimension of secondary transform input (and inverse secondary
//   transform output).
// - Height: dimension of secondary transform output (and inverse secondary
//   transform input).
#define IST_4x4_WIDTH 16
#define IST_4x4_HEIGHT 8
#define IST_8x8_HEIGHT_RED 20
#define IST_8x8_WIDTH_MAX 64
#define IST_8x8_WIDTH 48
#define IST_8x8_HEIGHT_MAX 32
#define IST_8x8_HEIGHT 32
#define IST_ADST_NZ_CNT 20

#define STX_SYNTAX_DEBUG 0
#define STX_COEFF_DEBUG 0

#define FSC_MODES 2
#define FSC_MAXWIDTH 32
#define FSC_MAXHEIGHT 32
#define FSC_MINWIDTH 4
#define FSC_MINHEIGHT 4

#define DIST_PRECISION_BITS 4

#define IBC_TOP_INTERP_BORDER 0
#define IBC_LEFT_INTERP_BORDER 0
#define IBC_RIGHT_INTERP_BORDER 1
#define IBC_BOTTOM_INTERP_BORDER 1

#define DMVR_SEARCH_NUM_NEIGHBORS 24
#define MULTI_SEQ_CONFIG_BITS 6
#define PROFILE_BITS 5
#define CONFIG_BITS 6
#define INTEROP_BITS 4
// Refer to Table A.1 in annexA.c
enum {
  MAIN_420_10_IP0 = 0,
  MAIN_420_10_IP1 = 1,
  MAIN_420_10_IP2 = 2,
  MAIN_422_10_IP1 = 3,
  MAIN_444_10_IP1 = 4,
#if CONFIG_TESTONLY_12BIT_SUPPORT
  // Fake profile value only for testing 12-bit. Not defined in AV2 spec.
  TEST_ONLY_12BIT_PROFILE,
#endif  // CONFIG_TESTONLY_12BIT_SUPPORT
  RESERVED_PROFILES_START,
  CONFIGURABLE = 31,
  MAX_PROFILES,
} SENUM1BYTE(BITSTREAM_PROFILE);

#define BUFFER_POOL_MAX_SIZE 18  // Max VBI slots (16) + 2 extra

#define MAX_NUM_TLAYERS 4
#define MAX_NUM_MLAYERS 8
#define MAX_NUM_XLAYERS 32
#define RESERVED_NUM_MLAYERS -1
// bits for temporal, embedded, and extended layers
#define TLAYER_BITS 2  // 2 bits for MAX_NUM_TLAYERS
#define MLAYER_BITS 3  // 3 bits for MAX_NUM_MLAYERS
#define XLAYER_BITS 5  // 5 bits for MAX_NUM_XLAYERS
#define MAX_NUM_OPERATING_POINTS (MAX_NUM_TLAYERS * MAX_NUM_MLAYERS)
#define OP_POINTS_CNT_MINUS_1_BITS (TLAYER_BITS + MLAYER_BITS)
#define OP_POINTS_IDC_BITS (MAX_NUM_TLAYERS + MAX_NUM_MLAYERS)

// LCR
#define LCR_ID_BITS 3
#define MAX_NUM_LCR (1 << LCR_ID_BITS)
#define MAX_LCR_TYPES 2
#define GLOBAL_XLAYER_ID 31
// OPS
#define OPS_ID_BITS 4
#define MAX_NUM_OPS_ID (1 << OPS_ID_BITS)
#define OPS_COUNT_BITS 3
#define MAX_OPS_COUNT ((1 << OPS_COUNT_BITS) - 1)
// Atlas
#define MAX_ATLAS_REGIONS 64  // maximum number of Atlas regions per dimension
#define ATLAS_SEG_ID_BITS 3
#define MAX_NUM_ATLAS_SEG_ID (1 << ATLAS_SEG_ID_BITS)
#define ATLAS_LABEL_SEG_ID_BITS 8
#define MAX_NUM_ATLAS_SEGMENTS (1 << ATLAS_LABEL_SEG_ID_BITS)

// Enabling this macro removes the prompting in lcr_profile_tier_level() to be
// included after profile, tier and level definitions are finalized.
// TODO: remove this macro after definition of profile, tier and level
#define MULTILAYER_HLS_REMOVE_LOGS 1

#define MAX_NUM_SEQ_LCR_ID 7
#define LCR_ID_UNSPECIFIED 0

enum {
  TEXTURE_LAYER = 0,
  AUX_LAYER = 1,
  STEREO_LAYER = 2,
  DEPENDENT_LAYER = 3,
  // Reserved: 4-15
  LAYER_TYPES = 16
};

enum {
  LCR_ALPHA_AUX = 0,
  LCR_DEPTH_AUX = 1,
  LCR_SEGMENTATION_AUX = 2,
  LCR_GAIN_MAP_AUX = 3,
  // 4-127: Reserved (for future AOMedia use)
  LCR_AUX_TYPE_RESERVED_START = 4,
  LCR_AUX_TYPE_RESERVED_END = 127,
  // 128-159: Unspecified (interpretation defined through external means)
  LCR_AUX_TYPE_UNSPECIFIED_START = 128,
  LCR_AUX_TYPE_UNSPECIFIED_END = 159,
  // 160-255: Reserved (for future AOMedia use)
  LCR_AUX_TYPE_RESERVED2_START = 160,
  LCR_AUX_TYPE_RESERVED2_END = 255,
};

enum {
  VIEW_UNSPECIFIED = 0,
  VIEW_CENTER = 1,
  VIEW_LEFT = 2,
  VIEW_RIGHT = 3,
  VIEW_EXPLICIT = 4,
  // Reserved: 5-7
  VIEW_TYPES = 8
};

enum {
  ENHANCED_ATLAS = 0,
  BASIC_ATLAS = 1,
  SINGLE_ATLAS = 2,
  MULTISTREAM_ATLAS = 3,
  MULTISTREAM_ALPHA_ATLAS = 4,
  ATLAS_TYPES
};

enum {
  UNSPECIFIED_MULTIVIEW,
  STEREOSCOPIC_VIEWPORTS,
  IMMERSIVE_MULTIPLE_VIEWPORTS,
  IMMERSIVE_MULTIPLE_VIEWPORTS_ALPHA,
  IMMERSIVE_MULTIPLE_VIEWPORTS_DEPTH,
  IMMERSIVE_MULTIPLE_VIEWPORTS_ALPHA_DEPTH,
  MULTIVIEW_PLAYBACK,
  SUBREGION_PLAYBACK,
  GLOBAL_PURPOSE_ID_TYPES
};

// Note: Some enums use the attribute 'packed' to use smallest possible integer
// type, so that we can save memory when they are used in structs/arrays.

typedef enum ATTRIBUTE_PACKED {
  BLOCK_4X4,
  BLOCK_4X8,
  BLOCK_8X4,
  BLOCK_8X8,
  BLOCK_8X16,
  BLOCK_16X8,
  BLOCK_16X16,
  BLOCK_16X32,
  BLOCK_32X16,
  BLOCK_32X32,
  BLOCK_32X64,
  BLOCK_64X32,
  BLOCK_64X64,
  BLOCK_64X128,
  BLOCK_128X64,
  BLOCK_128X128,
  BLOCK_128X256,
  BLOCK_256X128,
  BLOCK_256X256,
  BLOCK_4X16,
  BLOCK_16X4,
  BLOCK_8X32,
  BLOCK_32X8,
  BLOCK_16X64,
  BLOCK_64X16,
  BLOCK_4X32,
  BLOCK_32X4,
  BLOCK_8X64,
  BLOCK_64X8,
  BLOCK_SIZES_ALL,
  BLOCK_LARGEST = BLOCK_256X256,
  BLOCK_SIZES = BLOCK_4X32,
  BLOCK_INVALID = 255,
} BLOCK_SIZE;

static AVM_INLINE BLOCK_SIZE get_larger_sqr_bsize(BLOCK_SIZE bsize) {
  switch (bsize) {
    case BLOCK_4X4:
    case BLOCK_4X8:
    case BLOCK_8X4: return BLOCK_8X8;

    case BLOCK_8X8:
    case BLOCK_8X16:
    case BLOCK_16X8:
    case BLOCK_4X16:
    case BLOCK_16X4: return BLOCK_16X16;

    case BLOCK_16X16:
    case BLOCK_16X32:
    case BLOCK_32X16:
    case BLOCK_8X32:
    case BLOCK_32X8: return BLOCK_32X32;

    case BLOCK_32X32:
    case BLOCK_32X64:
    case BLOCK_64X32:
    case BLOCK_16X64:
    case BLOCK_64X16: return BLOCK_64X64;

    case BLOCK_64X64:
    case BLOCK_64X128:
    case BLOCK_128X64:
    case BLOCK_128X128: return BLOCK_128X128;
    default: return BLOCK_INVALID;
  }
}

enum {
  SHARED_PART = 0,
  LUMA_PART = 1,
  CHROMA_PART = 2,
  TREES_TYPES,
} UENUM1BYTE(TREE_TYPE);

enum {
  INTRA_REGION = 0,
  MIXED_INTER_INTRA_REGION = 1,
  REGION_TYPES = 2,
} UENUM1BYTE(REGION_TYPE);

//  Partition types.  R: Recursive
//
//  NONE          HORZ          VERT          SPLIT
//  +-------+     +-------+     +---+---+     +---+---+
//  |       |     |       |     |   |   |     | R | R |
//  |       |     +-------+     |   |   |     +---+---+
//  |       |     |       |     |   |   |     | R | R |
//  +-------+     +-------+     +---+---+     +---+---+
//
//  HORZ_3                 VERT_3
//  +---------------+       +---+------+---+
//  |               |       |   |      |   |
//  +---------------+       |   |      |   |
//  |       |       |       |   |______|   |
//  |       |       |       |   |      |   |
//  +---------------+       |   |      |   |
//  |               |       |   |      |   |
//  +---------------+       +---+------+---+
//  HORZ_4A                 HORZ_4B
//  +---------------+       +---------------+
//  |               |       |               |
//  +---------------+       +---------------+
//  |               |       |               |
//  |               |       |               |
//  +---------------+       |               |
//  |               |       |               |
//  |               |       +---------------+
//  |               |       |               |
//  |               |       |               |
//  +---------------+       +---------------+
//  |               |       |               |
//  +---------------+       +---------------+
//
//  VERT_4A                                 VERT_4B
//  +-------------------------+          +-------------------------+
//  |   |      |          |   |          |   |          |      |   |
//  |   |      |          |   |          |   |          |      |   |
//  |   |      |          |   |          |   |          |      |   |
//  +-------------------------+          +-------------------------+
enum {
  PARTITION_NONE,
  PARTITION_HORZ,
  PARTITION_VERT,
  PARTITION_HORZ_3,  // 3 horizontal sub-partitions with ratios 4:1, 2:1 and 4:1
  PARTITION_VERT_3,  // 3 vertical sub-partitions with ratios 4:1, 2:1 and 4:1
  PARTITION_HORZ_4A,  // 4 horizontal uneven sub-partitions (1:2:4:1).
  PARTITION_HORZ_4B,  // 4 horizontal uneven sub-partitions (1:4:2:1).
  PARTITION_VERT_4A,  // 4 vertical uneven sub-partitions (1:2:4:1).
  PARTITION_VERT_4B,  // 4 vertical uneven sub-partitions (1:4:2:1).
  PARTITION_SPLIT,
  EXT_PARTITION_TYPES = PARTITION_SPLIT,
  ALL_PARTITION_TYPES = EXT_PARTITION_TYPES + 1,
  PARTITION_TYPES = PARTITION_VERT + 1,
  PARTITION_INVALID = 255
} UENUM1BYTE(PARTITION_TYPE);

// Rectangular partition types.
enum {
  HORZ = 0,
  VERT,
  NUM_RECT_PARTS,
  RECT_INVALID = NUM_RECT_PARTS
} UENUM1BYTE(RECT_PART_TYPE);

// Uneven 4-way partition types.
enum {
  UNEVEN_4A = 0,
  UNEVEN_4B,
  NUM_UNEVEN_4WAY_PARTS,
} UENUM1BYTE(UNEVEN_4WAY_PART_TYPE);

typedef char PARTITION_CONTEXT;
#define PARTITION_PLOFFSET 4  // number of probability models per block size

#define PARTITION_BLOCK_SIZES BLOCK_SIZES
#define SQUARE_SPLIT_CONTEXTS (2 * PARTITION_PLOFFSET)

// Extended SDP is only allowed for block samples >= 64 and <= 1024. The allowed
// block size group is 64, 128, 256, 512, 1024, so the number of block size
// group is 5 in total.
#define INTER_SDP_BSIZE_GROUP 4
#define INTER_SDP_MAX_BLOCK_SIZE 64
// block transform size
enum {
  TX_4X4,             // 4x4 transform
  TX_8X8,             // 8x8 transform
  TX_16X16,           // 16x16 transform
  TX_32X32,           // 32x32 transform
  TX_64X64,           // 64x64 transform
  TX_4X8,             // 4x8 transform
  TX_8X4,             // 8x4 transform
  TX_8X16,            // 8x16 transform
  TX_16X8,            // 16x8 transform
  TX_16X32,           // 16x32 transform
  TX_32X16,           // 32x16 transform
  TX_32X64,           // 32x64 transform
  TX_64X32,           // 64x32 transform
  TX_4X16,            // 4x16 transform
  TX_16X4,            // 16x4 transform
  TX_8X32,            // 8x32 transform
  TX_32X8,            // 32x8 transform
  TX_16X64,           // 16x64 transform
  TX_64X16,           // 64x16 transform
  TX_4X32,            // 4x32 transform
  TX_32X4,            // 32x4 transform
  TX_8X64,            // 8x64 transform
  TX_64X8,            // 64x8 transform
  TX_4X64,            // 4x64 transform
  TX_64X4,            // 64x4 transform
  TX_SIZES_ALL,       // Includes rectangular transforms
  TX_SIZES = TX_4X8,  // Does NOT include rectangular transforms
  TX_SIZES_LARGEST = TX_64X64,
  TX_INVALID = 255  // Invalid transform size
} UENUM1BYTE(TX_SIZE);

//  Baseline transform partition types
//
//  Square:
//  NONE           SPLIT
//  +-------+      +---+---+
//  |       |      |   |   |
//  |       |      +---+---+
//  |       |      |   |   |
//  +-------+      +---+---+
//
//
//  Rectangular:
//  NONE                  SPLIT
//  +--------------+      +-------+-------+
//  |              |      |       |       |
//  |              |      +       +       +
//  |              |      |       |       |
//  +--------------+      +-------+-------+
//
//  Extended transform partition types (square and rect are the same)
//
//  NONE           SPLIT
//  +-------+      +---+---+
//  |       |      |   |   |
//  |       |      +---+---+
//  |       |      |   |   |
//  +-------+      +---+---+
//
//  HORZ            VERT
//  +-------+      +---+---+
//  |       |      |   |   |
//  +-------+      |   |   |
//  |       |      |   |   |
//  +-------+      +---+---+
//
//  HORZ4          VERT4
//  +-------+      +--+--+--+--+
//  |       |      |  |  |  |  |
//  +-------+      |  |  |  |  |
//  |       |      |  |  |  |  |
//  +-------+      |  |  |  |  |
//  |       |      +--+--+--+--+
//  +-------+
//  |       |
//  +-------+
//
//  HORZ5          VERT5
//  +---+---+      +--+----+--+
//  |   |   |      |  |    |  |
//  +---+---+      +--+    +--+
//  |       |      |  |    |  |
//  |       |      +--+----+--+
//  +---+---+
//  |   |   |
//  +---+---+
enum {
  TX_PARTITION_NONE,
  TX_PARTITION_SPLIT,
  TX_PARTITION_HORZ,
  TX_PARTITION_VERT,
  TX_PARTITION_HORZ4,
  TX_PARTITION_VERT4,
  TX_PARTITION_HORZ5,
  TX_PARTITION_VERT5,
  TX_PARTITION_TYPES,
  TX_PARTITION_INVALID = 255
} UENUM1BYTE(TX_PARTITION_TYPE);

#define TX_PARTITION_TYPE_NUM (TX_PARTITION_TYPES - 1)
#define TX_PARTITION_TYPE_NUM_VERT_AND_HORZ 14
#define TX_PARTITION_TYPE_NUM_VERT_OR_HORZ 3
#define TX_PARTITION_DIRS 2  // Horizontal and vertical.

#define MAX_TX_SIZE_LOG2 (6)
#define MAX_TX_SIZE (1 << MAX_TX_SIZE_LOG2)
#define MIN_TX_SIZE_LOG2 2
#define MIN_TX_SIZE (1 << MIN_TX_SIZE_LOG2)
#define MAX_TX_SQUARE (MAX_TX_SIZE * MAX_TX_SIZE)
#define MAX_TRELLIS 1024

#define TX_PAD_HOR_LOG2 2
#define TX_PAD_HOR 4
#define TX_PAD_LEFT 4
#define TX_PAD_TOP 4
#define TX_PAD_BOTTOM 4
#define TX_PAD_VER (TX_PAD_TOP + TX_PAD_BOTTOM)
// Pad 16 extra bytes to avoid reading overflow in SIMD optimization.
#define TX_PAD_END 16
#define TX_PAD_2D ((32 + TX_PAD_HOR) * (32 + TX_PAD_VER) + TX_PAD_END)

// Number of maxium size transform blocks in the maximum size superblock
#define MAX_TX_BLOCKS_IN_MAX_SB_LOG2 ((MAX_SB_SIZE_LOG2 - MAX_TX_SIZE_LOG2) * 2)
#define MAX_TX_BLOCKS_IN_MAX_SB (1 << MAX_TX_BLOCKS_IN_MAX_SB_LOG2)

// frame transform mode
enum {
  ONLY_4X4,         // use only 4x4 transform
  TX_MODE_LARGEST,  // transform size is the largest possible for pu size
  TX_MODE_SELECT,   // transform specified for each block
  TX_MODES,
} UENUM1BYTE(TX_MODE);

// 1D tx types
enum {
  DCT_1D,
  ADST_1D,
  FLIPADST_1D,
  IDTX_1D,
  DDT_1D,
  TX_TYPES_1D,
} UENUM1BYTE(TX_TYPE_1D);

enum {
  DCT_DCT,            // DCT in both horizontal and vertical
  ADST_DCT,           // ADST in vertical, DCT in horizontal
  DCT_ADST,           // DCT in vertical, ADST in horizontal
  ADST_ADST,          // ADST in both directions
  FLIPADST_DCT,       // FLIPADST in vertical, DCT in horizontal
  DCT_FLIPADST,       // DCT in vertical, FLIPADST in horizontal
  FLIPADST_FLIPADST,  // FLIPADST in both directions
  ADST_FLIPADST,      // ADST in vertical, FLIPADST in horizontal
  FLIPADST_ADST,      // FLIPADST in vertical, ADST in horizontal
  IDTX,               // Identity in both directions
  V_DCT,              // DCT in vertical, identity in horizontal
  H_DCT,              // Identity in vertical, DCT in horizontal
  V_ADST,             // ADST in vertical, identity in horizontal
  H_ADST,             // Identity in vertical, ADST in horizontal
  V_FLIPADST,         // FLIPADST in vertical, identity in horizontal
  H_FLIPADST,         // Identity in vertical, FLIPADST in horizontal
  TX_TYPES,
  DCT_ADST_TX_MASK = 0x000F,  // Either DCT or ADST in each direction
} UENUM2BYTE(TX_TYPE);

enum {
  DCT2,
  IDT,
  DST7,
  DCT8,
  DDTX,
  FDDT,
} UENUM2BYTE(TX1D_TYPE);

enum {
  CCTX_NONE,     // No cross chroma transform
  CCTX_45,       // 45 degrees rotation (Haar transform)
  CCTX_30,       // 30 degrees rotation
  CCTX_60,       // 60 degrees rotation
  CCTX_MINUS45,  // -45 degrees rotation
  CCTX_MINUS30,  // -30 degrees rotation
  CCTX_MINUS60,  // -60 degrees rotation
  CCTX_TYPES,
  CCTX_START = CCTX_NONE + 1,
} UENUM1BYTE(CctxType);

enum { FWD_TXFM, INV_TXFM, TXFM_DIRECTIONS } UENUM1BYTE(TXFM_DIRECTION);

enum {
  // DCT only
  EXT_TX_SET_DCTONLY,
  // DCT + Identity only
  EXT_TX_SET_DCT_IDTX,
  // DCT_DCT + ADST_DCT/DCT_ADST + FLIPADST_DCT/DCT_FLIPADST + H_DCT/V_DCT
  EXT_TX_SET_LONG_SIDE_64,
  // DCT_DCT + Identity + ADST_DCT/DCT_ADST + FLIPADST_DCT/DCT_FLIPADST +
  // H_DCT/V_DCT
  EXT_TX_SET_LONG_SIDE_32,

  // Discrete Trig transforms w/o flip (4) + Identity (1)
  EXT_TX_SET_DTT4_IDTX,
  // Discrete Trig transforms w/o flip (4) + Identity (1) + 1D Hor/vert DCT (2)
  EXT_TX_SET_DTT4_IDTX_1DDCT,
  // Discrete Trig transforms w/ flip (9) + Identity (1) + 1D Hor/Ver DCT (2)
  EXT_TX_SET_DTT9_IDTX_1DDCT,
  // Discrete Trig transforms w/ flip (9) + Identity (1) + 1D Hor/Ver (6)
  EXT_TX_SET_ALL16,
  EXT_NEW_TX_SET,
  // DCT + Identity (1) + 1D Hor/vert DCT (2)
  EXT_TX_SET_DCT_IDTX_IDDCT,
  EXT_TX_SET_TYPES
} UENUM1BYTE(TxSetType);

#define EOB_TX_CTXS 3
#define EXT_TX_SIZES 4  // number of sizes that use extended transforms

#define EXT_TX_SETS_INTER 5  // Sets of transform selections for INTER
#define INTER_TX_SET1 16
#define INTER_TX_SET2 12
#define INTER_TX_SET3 2
#define INTER_TX_SET4 4

#define EXT_TX_SETS_INTRA 3  // Sets of transform selections for INTRA
#define INTRA_TX_SET1 7
#define INTRA_TX_SET2 2

enum { PLANE_TYPE_Y, PLANE_TYPE_UV, PLANE_TYPES } UENUM1BYTE(PLANE_TYPE);

#define CFL_ALPHABET_SIZE_LOG2 3
#define CFL_ALPHABET_SIZE (1 << CFL_ALPHABET_SIZE_LOG2)
#define CFL_IDX_U(idx) (idx >> CFL_ALPHABET_SIZE_LOG2)
#define CFL_IDX_V(idx) (idx & (CFL_ALPHABET_SIZE - 1))

enum { CFL_PRED_U, CFL_PRED_V, CFL_PRED_PLANES } UENUM1BYTE(CFL_PRED_TYPE);

enum {
  CFL_SIGN_ZERO,
  CFL_SIGN_NEG,
  CFL_SIGN_POS,
  CFL_SIGNS
} UENUM1BYTE(CFL_SIGN_TYPE);

enum {
  CFL_DISALLOWED,
  CFL_ALLOWED,
  CFL_ALLOWED_TYPES
} UENUM1BYTE(CFL_ALLOWED_TYPE);

enum {
  MHCCP_DISALLOWED,
  MHCCP_ALLOWED,
  MHCCP_ALLOWED_TYPES
} UENUM1BYTE(MHCCP_ALLOWED_TYPE);

enum {
  CFL_DISALLOWED_FOR_CHROMA,
  CFL_ALLOWED_FOR_CHROMA,
  CFL_ALLOWED_TYPES_FOR_SDP
} UENUM1BYTE(CFL_ALLOWED_FOR_SDP_TYPE);

// CFL_SIGN_ZERO,CFL_SIGN_ZERO is invalid
#define CFL_JOINT_SIGNS (CFL_SIGNS * CFL_SIGNS - 1)
// CFL_SIGN_U is equivalent to (js + 1) / 3 for js in 0 to 8
#define CFL_SIGN_U(js) (((js + 1) * 11) >> 5)
// CFL_SIGN_V is equivalent to (js + 1) % 3 for js in 0 to 8
#define CFL_SIGN_V(js) ((js + 1) - CFL_SIGNS * CFL_SIGN_U(js))

// There is no context when the alpha for a given plane is zero.
// So there are 2 fewer contexts than joint signs.
#define CFL_ALPHA_CONTEXTS (CFL_JOINT_SIGNS + 1 - CFL_SIGNS)
#define CFL_CONTEXT_U(js) (js + 1 - CFL_SIGNS)
// Also, the contexts are symmetric under swapping the planes.
#define CFL_CONTEXT_V(js) \
  (CFL_SIGN_V(js) * CFL_SIGNS + CFL_SIGN_U(js) - CFL_SIGNS)

enum {
  PALETTE_MAP,
  COLOR_MAP_TYPES,
} UENUM1BYTE(COLOR_MAP_TYPE);

// Number of colors in a palette are from 2 to 8 inclusive.
// Hence total 7 options.
#define PALETTE_SIZES 7
#define PALETTE_COLORS 8

// Note: All directional predictors must be between V_PRED and D67_PRED (both
// inclusive).
enum {
  DC_PRED,        // Average of above and left pixels
  V_PRED,         // Vertical
  H_PRED,         // Horizontal
  D45_PRED,       // Directional 45  degree
  D135_PRED,      // Directional 135 degree
  D113_PRED,      // Directional 113 degree
  D157_PRED,      // Directional 157 degree
  D203_PRED,      // Directional 203 degree
  D67_PRED,       // Directional 67  degree
  SMOOTH_PRED,    // Combination of horizontal and vertical interpolation
  SMOOTH_V_PRED,  // Vertical interpolation
  SMOOTH_H_PRED,  // Horizontal interpolation
  PAETH_PRED,     // Predict from the direction of smallest gradient
  NEARMV,
  GLOBALMV,
  NEWMV,
  WARPMV,      // WARPMV mode (original WARPMV)
  WARP_NEWMV,  // WARP_NEWMV mode (original warp modes under NEWMV)
               // Compound ref compound modes
  NEAR_NEARMV,
  NEAR_NEWMV,
  NEW_NEARMV,
  GLOBAL_GLOBALMV,
  NEW_NEWMV,
  JOINT_NEWMV,
  NEAR_NEARMV_OPTFLOW,
  NEAR_NEWMV_OPTFLOW,
  NEW_NEARMV_OPTFLOW,
  NEW_NEWMV_OPTFLOW,
  JOINT_NEWMV_OPTFLOW,
  MB_MODE_COUNT,
  INTRA_MODE_START = DC_PRED,
  INTRA_MODE_END = NEARMV,
  DIR_MODE_START = V_PRED,
  DIR_MODE_END = D67_PRED + 1,
  INTRA_MODE_NUM = INTRA_MODE_END - INTRA_MODE_START,
  SINGLE_INTER_MODE_START = NEARMV,
  SINGLE_INTER_MODE_END = NEAR_NEARMV,
  SINGLE_INTER_MODE_NUM = SINGLE_INTER_MODE_END - SINGLE_INTER_MODE_START,
  COMP_INTER_MODE_START = NEAR_NEARMV,
  COMP_INTER_MODE_END = MB_MODE_COUNT,
  COMP_INTER_MODE_NUM = COMP_INTER_MODE_END - COMP_INTER_MODE_START,
  COMP_OPTFLOW_MODE_START = NEAR_NEARMV_OPTFLOW,
  INTER_COMPOUND_REF_TYPES = COMP_OPTFLOW_MODE_START - COMP_INTER_MODE_START,
  INTER_MODE_START = NEARMV,
  INTER_MODE_END = MB_MODE_COUNT,
  INTRA_MODES = PAETH_PRED + 1,   // PAETH_PRED has to be the last intra mode.
  INTRA_INVALID = MB_MODE_COUNT,  // For uv_mode in inter blocks
  MODE_INVALID = 255
} UENUM1BYTE(PREDICTION_MODE);

// TODO(ltrudeau) Do we really want to pack this?
// TODO(ltrudeau) Do we match with PREDICTION_MODE?
enum {
  UV_DC_PRED,        // Average of above and left pixels
  UV_V_PRED,         // Vertical
  UV_H_PRED,         // Horizontal
  UV_D45_PRED,       // Directional 45  degree
  UV_D135_PRED,      // Directional 135 degree
  UV_D113_PRED,      // Directional 113 degree
  UV_D157_PRED,      // Directional 157 degree
  UV_D203_PRED,      // Directional 203 degree
  UV_D67_PRED,       // Directional 67  degree
  UV_SMOOTH_PRED,    // Combination of horizontal and vertical interpolation
  UV_SMOOTH_V_PRED,  // Vertical interpolation
  UV_SMOOTH_H_PRED,  // Horizontal interpolation
  UV_PAETH_PRED,     // Predict from the direction of smallest gradient
  UV_CFL_PRED,       // Chroma-from-Luma
  UV_INTRA_MODES,
  UV_MODE_INVALID,  // For uv_mode in inter blocks
} UENUM1BYTE(UV_PREDICTION_MODE);

enum {
  CFL_EXPLICIT,       // av2 cfl
  CFL_DERIVED_ALPHA,  // implicit CfL mode with derived scaling factor
  CFL_MULTI_PARAM,    // multi hypothesis cross component prediction
  CFL_TYPE_COUNT,     // CfL mode type count
} UENUM1BYTE(CFL_TYPE);

// Number of top model rd to store for pruning y modes in intra mode decision
#define TOP_INTRA_MODEL_COUNT 6
#define TOP_TX_PART_COUNT 4
#define TOP_INTER_TX_PART_COUNT 8
// Total number of luma intra prediction modes (include both directional and
// non-directional modes)
#define LUMA_MODE_COUNT 61

enum {
  SIMPLE_TRANSLATION,
  INTERINTRA,
  WARP_CAUSAL,  // Warp estimation from spatial MVs
  WARP_DELTA,   // Directly-signaled warp model
  WARP_EXTEND,  // Extension of an existing warp model into another block
  MOTION_MODES
} UENUM1BYTE(MOTION_MODE);

#define OPFL_GRAD_UNIT_LOG2 4
#define OPFL_GRAD_UNIT (1 << OPFL_GRAD_UNIT_LOG2)

#define COMPOUND_WARP_LINE_BUFFER_REDUCTION 1

enum {
  II_DC_PRED,
  II_V_PRED,
  II_H_PRED,
  II_SMOOTH_PRED,
  INTERINTRA_MODES
} UENUM1BYTE(INTERINTRA_MODE);

enum {
  COMPOUND_AVERAGE,
  COMPOUND_WEDGE,
  COMPOUND_DIFFWTD,
  COMPOUND_TYPES,
  MASKED_COMPOUND_TYPES = 2,
} UENUM1BYTE(COMPOUND_TYPE);

enum {
  SEQ_LEVEL_2_0 = 0,
  SEQ_LEVEL_2_1 = 1,
  SEQ_LEVEL_3_0 = 2,
  SEQ_LEVEL_3_1 = 3,
  SEQ_LEVEL_4_0 = 4,
  SEQ_LEVEL_4_1 = 5,
  SEQ_LEVEL_5_0 = 6,
  SEQ_LEVEL_5_1 = 7,
  SEQ_LEVEL_5_2 = 8,
  SEQ_LEVEL_5_3 = 9,
  SEQ_LEVEL_6_0 = 10,
  SEQ_LEVEL_6_1 = 11,
  SEQ_LEVEL_6_2 = 12,
  SEQ_LEVEL_6_3 = 13,
  SEQ_LEVEL_7_0 = 14,
  SEQ_LEVEL_7_1 = 15,
  SEQ_LEVEL_7_2 = 16,
  SEQ_LEVEL_7_3 = 17,
  SEQ_LEVEL_8_0 = 18,
  SEQ_LEVEL_8_1 = 19,
  SEQ_LEVEL_8_2 = 20,
  SEQ_LEVEL_8_3 = 21,
  SEQ_LEVELS,
  SEQ_LEVEL_MAX = 31
} UENUM1BYTE(AV2_LEVEL);

#define LEVEL_BITS 5

#define DIRECTIONAL_MODES 8
#define MAX_ANGLE_DELTA 3
#define ANGLE_STEP 3

// Total delta angles for one nominal directional mode
#define TOTAL_ANGLE_DELTA_COUNT 7

// The warpmv and warpmv_new mode is signalled as a separate flag
// So the number of remaining modes to be signalled is (SINGLE_INTER_MODE_NUM-2)
#define INTER_SINGLE_MODES (SINGLE_INTER_MODE_NUM - 2)

#define SKIP_CONTEXTS 6
#define SKIP_MODE_CONTEXTS 3

#define INTRABC_CONTEXTS 3

#define NUM_ALLOWED_BV_PRECISIONS 2
#define NUM_BV_PRECISION_CONTEXTS 1
#define COMP_GROUP_IDX_CONTEXTS 12

#define MIN_MAX_DRL_BITS 1
#define MAX_MAX_DRL_BITS (MAX_REF_MV_STACK_SIZE - 1)

#define WARPMV_MODE_CONTEXT 5
#define MAX_REF_BV_STACK_SIZE 4
#define MIN_MAX_IBC_DRL_BITS 1
#define MAX_MAX_IBC_DRL_BITS (MAX_REF_BV_STACK_SIZE - 1)

#define OPFL_MODE_CONTEXTS 2

#define INTER_MODE_CONTEXTS 5
#define DRL_MODE_CONTEXTS INTER_MODE_CONTEXTS

#define INTER_COMPOUND_SAME_REFS_TYPES (INTER_COMPOUND_REF_TYPES - 2)

// Explicit BAWP scaling factor counts
#define EXPLICIT_BAWP_SCALE_CNT 2
// Explicit BAWP scaling factor context counts
#define BAWP_SCALES_CTX_COUNT 3
// The allowed value range for bawp_flag
#define BAWP_REF_LINES 1
#define BAWP_OPTION_CNT 4

#define AMVD_MODE_CONTEXTS 3
#define NUM_AMVD_MODES 9

// Number of supported factors for compound weighted prediction
#define MAX_CWP_NUM 5
// maximum value for the supported factors
#define CWP_MAX 20
// minimum value for the supported factors
#define CWP_MIN -4
// Weighting factor for simple averge prediction
#define CWP_EQUAL 8
#define CWP_WEIGHT_BITS 4
#define MAX_CWP_CONTEXTS 2

// Number of supported factors for TIP weights
#define MAX_TIP_WTD_NUM 8
#define TIP_EQUAL_WTD 8
#define TIP_SINGLE_WTD 16
#define MAX_AMVD_INDEX 8

#define DELTA_Q_SMALL 7
#define DELTA_Q_SMALL_MINUS_2 (DELTA_Q_SMALL - 2)
#define DELTA_Q_PROBS (DELTA_Q_SMALL)
#define DEFAULT_DELTA_Q_RES_PERCEPTUAL 4
#define DEFAULT_DELTA_Q_RES_OBJECTIVE 4

#define MAX_MV_REF_CANDIDATES 2
#define MAX_REF_MV_STACK_SIZE 6
#define USABLE_REF_MV_STACK_SIZE (MAX_REF_MV_STACK_SIZE)

#define REF_CAT_LEVEL 0

#define MAX_WARP_REF_CANDIDATES 4
#define WARP_REF_CONTEXTS 1

#define INTRA_INTER_CONTEXTS 4
#define COMP_INTER_CONTEXTS 5
#define REF_CONTEXTS 3

// Group size from mapping block size to tx partition context
#define TXFM_SPLIT_GROUP 9
typedef uint16_t TXFM_CONTEXT;

#define TIP_CONTEXTS 3

#define MAX_MFH_NUM 16
#define WARP_CAUSAL_MODE_CTX 4

#define TIP_PRED_MODES 2
#define WARP_EXTEND_CTX 3

#define INTER_REFS_PER_FRAME 7

#define MAX_NUM_LONG_TERM_FRAMES INTER_REFS_PER_FRAME

// log 2 of max 8 references per-frame (7 inter + 1 intra)
// log2(INTER_REFS_PER_FRAME + 1)
#define MAX_REFS_PER_FRAME_LOG2 3

#define REF_FRAMES 16

// NOTE: A limited number of unidirectional reference pairs can be signalled for
//       compound prediction. The use of skip mode, on the other hand, makes it
//       possible to have a reference pair not listed for explicit signaling.
#define MODE_CTX_REF_FRAMES                                \
  (INTER_REFS_PER_FRAME * (INTER_REFS_PER_FRAME + 3) / 2 + \
   2)  // additional combinations for the same reference of compound mode

// With k=INTER_REFS_PER_FRAMES, indices 0 to k-1 represent rank 1 to rank k
// references. The next k(k-1)/2 indices are left for compound reference types
// (there are k choose 2 compound combinations). Then, index for intra frame is
// defined as k+k(k-1)/2.
#define INTRA_FRAME                                    \
  (INTER_REFS_PER_FRAME * (INTER_REFS_PER_FRAME + 3) / \
   2)  // additional combinations for the same reference of compound mode
// Used for indexing into arrays that contain reference data for
// inter and intra.
#define INTRA_FRAME_INDEX INTER_REFS_PER_FRAME
#define NONE_FRAME INVALID_IDX
#define AVM_REFFRAME_ALL ((1 << INTER_REFS_PER_FRAME) - 1)

// REF_FRAMES for the cm->ref_frame_map array, 1 scratch frame for the new
// frame in cm->cur_frame, INTER_REFS_PER_FRAME for scaled references on the
// encoder in the cpi->scaled_ref_buf array.
// Each substream has its own sub-DPB.
#define FRAME_BUFFERS \
  (REF_FRAMES + 1 + INTER_REFS_PER_FRAME) * AVM_MAX_NUM_STREAMS

#define TIP_FRAME (MODE_CTX_REF_FRAMES - 1)
#define TIP_FRAME_INDEX (INTER_REFS_PER_FRAME + 1)
#define SINGLE_REF_FRAMES (INTER_REFS_PER_FRAME + 2)
#define MAX_COMPOUND_REF_INDEX (SINGLE_REF_FRAMES - 1)

// Note: It includes single and compound references. So, it can take values from
// NONE_FRAME to (MODE_CTX_REF_FRAMES - 1). Hence, it is not defined as an enum.
typedef int8_t MV_REFERENCE_FRAME;

#define MAX_LR_FLEX_SWITCHABLE_BITS 3

/*!\endcond */

/*!\enum RestorationType
 * \brief This enumeration defines various restoration types supported
 */
typedef enum {
  RESTORE_NONE,          /**< No restoration */
  RESTORE_PC_WIENER,     /**< Pixel-classified Wiener restoration */
  RESTORE_WIENER_NONSEP, /**< Nonseparable Wiener restoration */
  RESTORE_SWITCHABLE,    /**< Switchable restoration */
  RESTORE_SWITCHABLE_TYPES = RESTORE_SWITCHABLE, /**< Num Switchable types */
  RESTORE_TYPES = RESTORE_SWITCHABLE + 1,        /**< Num Restore types */
} RestorationType;

/*!\cond */
// Picture prediction structures (0-12 are predefined) in scalability metadata.
enum {
  SCALABILITY_L1T2 = 0,
  SCALABILITY_L1T3 = 1,
  SCALABILITY_L2T1 = 2,
  SCALABILITY_L2T2 = 3,
  SCALABILITY_L2T3 = 4,
  SCALABILITY_S2T1 = 5,
  SCALABILITY_S2T2 = 6,
  SCALABILITY_S2T3 = 7,
  SCALABILITY_L2T1h = 8,
  SCALABILITY_L2T2h = 9,
  SCALABILITY_L2T3h = 10,
  SCALABILITY_S2T1h = 11,
  SCALABILITY_S2T2h = 12,
  SCALABILITY_S2T3h = 13,
  SCALABILITY_SS = 14
} UENUM1BYTE(SCALABILITY_STRUCTURES);

#define DIV_LUT_PREC_BITS 9
#define DIV_LUT_BITS 7

#define DIR_MODES_0_90 17
#define IBP_WEIGHT_SHIFT DIV_LUT_BITS

#define IBP_WEIGHT_MAX (1 << IBP_WEIGHT_SHIFT)
#define IBP_WEIGHT_REF IBP_WEIGHT_MAX
typedef uint16_t IbpWeightsType;

/*!\enum Warp projection type
 * \brief This enumeration defines various warp projection type supported
 */
typedef enum {
  PROJ_GLOBAL_MOTION,  /**< block is from global motion */
  PROJ_SPATIAL,        /**< Project from spatial neighborhood */
  PROJ_PARAM_BANK,     /**< Project from circular buffer */
  PROJ_DEFAULT,        /**< Default values */
  WARP_PROJ_TYPES = 4, /**< Num projection types */
} WarpProjectionType;

/*!\endcond */

#ifdef __cplusplus
}  // extern "C"
#endif

#endif  // AVM_AV2_COMMON_ENUMS_H_
