text:
# Automatically generated using Clang.jl wrap_c, version 0.0.0

export
    unix,
    linux,
    AVCodecID,
    AV_CODEC_ID_NONE,
    AV_CODEC_ID_MPEG1VIDEO,
    AV_CODEC_ID_MPEG2VIDEO,
    AV_CODEC_ID_H261,
    AV_CODEC_ID_H263,
    AV_CODEC_ID_RV10,
    AV_CODEC_ID_RV20,
    AV_CODEC_ID_MJPEG,
    AV_CODEC_ID_MJPEGB,
    AV_CODEC_ID_LJPEG,
    AV_CODEC_ID_SP5X,
    AV_CODEC_ID_JPEGLS,
    AV_CODEC_ID_MPEG4,
    AV_CODEC_ID_RAWVIDEO,
    AV_CODEC_ID_MSMPEG4V1,
    AV_CODEC_ID_MSMPEG4V2,
    AV_CODEC_ID_MSMPEG4V3,
    AV_CODEC_ID_WMV1,
    AV_CODEC_ID_WMV2,
    AV_CODEC_ID_H263P,
    AV_CODEC_ID_H263I,
    AV_CODEC_ID_FLV1,
    AV_CODEC_ID_SVQ1,
    AV_CODEC_ID_SVQ3,
    AV_CODEC_ID_DVVIDEO,
    AV_CODEC_ID_HUFFYUV,
    AV_CODEC_ID_CYUV,
    AV_CODEC_ID_H264,
    AV_CODEC_ID_INDEO3,
    AV_CODEC_ID_VP3,
    AV_CODEC_ID_THEORA,
    AV_CODEC_ID_ASV1,
    AV_CODEC_ID_ASV2,
    AV_CODEC_ID_FFV1,
    AV_CODEC_ID_4XM,
    AV_CODEC_ID_VCR1,
    AV_CODEC_ID_CLJR,
    AV_CODEC_ID_MDEC,
    AV_CODEC_ID_ROQ,
    AV_CODEC_ID_INTERPLAY_VIDEO,
    AV_CODEC_ID_XAN_WC3,
    AV_CODEC_ID_XAN_WC4,
    AV_CODEC_ID_RPZA,
    AV_CODEC_ID_CINEPAK,
    AV_CODEC_ID_WS_VQA,
    AV_CODEC_ID_MSRLE,
    AV_CODEC_ID_MSVIDEO1,
    AV_CODEC_ID_IDCIN,
    AV_CODEC_ID_8BPS,
    AV_CODEC_ID_SMC,
    AV_CODEC_ID_FLIC,
    AV_CODEC_ID_TRUEMOTION1,
    AV_CODEC_ID_VMDVIDEO,
    AV_CODEC_ID_MSZH,
    AV_CODEC_ID_ZLIB,
    AV_CODEC_ID_QTRLE,
    AV_CODEC_ID_TSCC,
    AV_CODEC_ID_ULTI,
    AV_CODEC_ID_QDRAW,
    AV_CODEC_ID_VIXL,
    AV_CODEC_ID_QPEG,
    AV_CODEC_ID_PNG,
    AV_CODEC_ID_PPM,
    AV_CODEC_ID_PBM,
    AV_CODEC_ID_PGM,
    AV_CODEC_ID_PGMYUV,
    AV_CODEC_ID_PAM,
    AV_CODEC_ID_FFVHUFF,
    AV_CODEC_ID_RV30,
    AV_CODEC_ID_RV40,
    AV_CODEC_ID_VC1,
    AV_CODEC_ID_WMV3,
    AV_CODEC_ID_LOCO,
    AV_CODEC_ID_WNV1,
    AV_CODEC_ID_AASC,
    AV_CODEC_ID_INDEO2,
    AV_CODEC_ID_FRAPS,
    AV_CODEC_ID_TRUEMOTION2,
    AV_CODEC_ID_BMP,
    AV_CODEC_ID_CSCD,
    AV_CODEC_ID_MMVIDEO,
    AV_CODEC_ID_ZMBV,
    AV_CODEC_ID_AVS,
    AV_CODEC_ID_SMACKVIDEO,
    AV_CODEC_ID_NUV,
    AV_CODEC_ID_KMVC,
    AV_CODEC_ID_FLASHSV,
    AV_CODEC_ID_CAVS,
    AV_CODEC_ID_JPEG2000,
    AV_CODEC_ID_VMNC,
    AV_CODEC_ID_VP5,
    AV_CODEC_ID_VP6,
    AV_CODEC_ID_VP6F,
    AV_CODEC_ID_TARGA,
    AV_CODEC_ID_DSICINVIDEO,
    AV_CODEC_ID_TIERTEXSEQVIDEO,
    AV_CODEC_ID_TIFF,
    AV_CODEC_ID_GIF,
    AV_CODEC_ID_DXA,
    AV_CODEC_ID_DNXHD,
    AV_CODEC_ID_THP,
    AV_CODEC_ID_SGI,
    AV_CODEC_ID_C93,
    AV_CODEC_ID_BETHSOFTVID,
    AV_CODEC_ID_PTX,
    AV_CODEC_ID_TXD,
    AV_CODEC_ID_VP6A,
    AV_CODEC_ID_AMV,
    AV_CODEC_ID_VB,
    AV_CODEC_ID_PCX,
    AV_CODEC_ID_SUNRAST,
    AV_CODEC_ID_INDEO4,
    AV_CODEC_ID_INDEO5,
    AV_CODEC_ID_MIMIC,
    AV_CODEC_ID_RL2,
    AV_CODEC_ID_ESCAPE124,
    AV_CODEC_ID_DIRAC,
    AV_CODEC_ID_BFI,
    AV_CODEC_ID_CMV,
    AV_CODEC_ID_MOTIONPIXELS,
    AV_CODEC_ID_TGV,
    AV_CODEC_ID_TGQ,
    AV_CODEC_ID_TQI,
    AV_CODEC_ID_AURA,
    AV_CODEC_ID_AURA2,
    AV_CODEC_ID_V210X,
    AV_CODEC_ID_TMV,
    AV_CODEC_ID_V210,
    AV_CODEC_ID_DPX,
    AV_CODEC_ID_MAD,
    AV_CODEC_ID_FRWU,
    AV_CODEC_ID_FLASHSV2,
    AV_CODEC_ID_CDGRAPHICS,
    AV_CODEC_ID_R210,
    AV_CODEC_ID_ANM,
    AV_CODEC_ID_BINKVIDEO,
    AV_CODEC_ID_IFF_ILBM,
    AV_CODEC_ID_KGV1,
    AV_CODEC_ID_YOP,
    AV_CODEC_ID_VP8,
    AV_CODEC_ID_PICTOR,
    AV_CODEC_ID_ANSI,
    AV_CODEC_ID_A64_MULTI,
    AV_CODEC_ID_A64_MULTI5,
    AV_CODEC_ID_R10K,
    AV_CODEC_ID_MXPEG,
    AV_CODEC_ID_LAGARITH,
    AV_CODEC_ID_PRORES,
    AV_CODEC_ID_JV,
    AV_CODEC_ID_DFA,
    AV_CODEC_ID_WMV3IMAGE,
    AV_CODEC_ID_VC1IMAGE,
    AV_CODEC_ID_UTVIDEO,
    AV_CODEC_ID_BMV_VIDEO,
    AV_CODEC_ID_VBLE,
    AV_CODEC_ID_DXTORY,
    AV_CODEC_ID_V410,
    AV_CODEC_ID_XWD,
    AV_CODEC_ID_CDXL,
    AV_CODEC_ID_XBM,
    AV_CODEC_ID_ZEROCODEC,
    AV_CODEC_ID_MSS1,
    AV_CODEC_ID_MSA1,
    AV_CODEC_ID_TSCC2,
    AV_CODEC_ID_MTS2,
    AV_CODEC_ID_CLLC,
    AV_CODEC_ID_MSS2,
    AV_CODEC_ID_VP9,
    AV_CODEC_ID_AIC,
    AV_CODEC_ID_ESCAPE130,
    AV_CODEC_ID_G2M,
    AV_CODEC_ID_WEBP,
    AV_CODEC_ID_HNM4_VIDEO,
    AV_CODEC_ID_HEVC,
    AV_CODEC_ID_FIC,
    AV_CODEC_ID_ALIAS_PIX,
    AV_CODEC_ID_BRENDER_PIX,
    AV_CODEC_ID_PAF_VIDEO,
    AV_CODEC_ID_EXR,
    AV_CODEC_ID_VP7,
    AV_CODEC_ID_SANM,
    AV_CODEC_ID_SGIRLE,
    AV_CODEC_ID_MVC1,
    AV_CODEC_ID_MVC2,
    AV_CODEC_ID_HQX,
    AV_CODEC_ID_TDSC,
    AV_CODEC_ID_HQ_HQA,
    AV_CODEC_ID_HAP,
    AV_CODEC_ID_DDS,
    AV_CODEC_ID_DXV,
    AV_CODEC_ID_SCREENPRESSO,
    AV_CODEC_ID_RSCC,
    AV_CODEC_ID_AVS2,
    AV_CODEC_ID_Y41P,
    AV_CODEC_ID_AVRP,
    AV_CODEC_ID_012V,
    AV_CODEC_ID_AVUI,
    AV_CODEC_ID_AYUV,
    AV_CODEC_ID_TARGA_Y216,
    AV_CODEC_ID_V308,
    AV_CODEC_ID_V408,
    AV_CODEC_ID_YUV4,
    AV_CODEC_ID_AVRN,
    AV_CODEC_ID_CPIA,
    AV_CODEC_ID_XFACE,
    AV_CODEC_ID_SNOW,
    AV_CODEC_ID_SMVJPEG,
    AV_CODEC_ID_APNG,
    AV_CODEC_ID_DAALA,
    AV_CODEC_ID_CFHD,
    AV_CODEC_ID_TRUEMOTION2RT,
    AV_CODEC_ID_M101,
    AV_CODEC_ID_MAGICYUV,
    AV_CODEC_ID_SHEERVIDEO,
    AV_CODEC_ID_YLC,
    AV_CODEC_ID_PSD,
    AV_CODEC_ID_PIXLET,
    AV_CODEC_ID_SPEEDHQ,
    AV_CODEC_ID_FMVC,
    AV_CODEC_ID_SCPR,
    AV_CODEC_ID_CLEARVIDEO,
    AV_CODEC_ID_XPM,
    AV_CODEC_ID_AV1,
    AV_CODEC_ID_BITPACKED,
    AV_CODEC_ID_MSCC,
    AV_CODEC_ID_SRGC,
    AV_CODEC_ID_SVG,
    AV_CODEC_ID_GDV,
    AV_CODEC_ID_FITS,
    AV_CODEC_ID_IMM4,
    AV_CODEC_ID_PROSUMER,
    AV_CODEC_ID_MWSC,
    AV_CODEC_ID_WCMV,
    AV_CODEC_ID_RASC,
    AV_CODEC_ID_FIRST_AUDIO,
    AV_CODEC_ID_PCM_S16LE,
    AV_CODEC_ID_PCM_S16BE,
    AV_CODEC_ID_PCM_U16LE,
    AV_CODEC_ID_PCM_U16BE,
    AV_CODEC_ID_PCM_S8,
    AV_CODEC_ID_PCM_U8,
    AV_CODEC_ID_PCM_MULAW,
    AV_CODEC_ID_PCM_ALAW,
    AV_CODEC_ID_PCM_S32LE,
    AV_CODEC_ID_PCM_S32BE,
    AV_CODEC_ID_PCM_U32LE,
    AV_CODEC_ID_PCM_U32BE,
    AV_CODEC_ID_PCM_S24LE,
    AV_CODEC_ID_PCM_S24BE,
    AV_CODEC_ID_PCM_U24LE,
    AV_CODEC_ID_PCM_U24BE,
    AV_CODEC_ID_PCM_S24DAUD,
    AV_CODEC_ID_PCM_ZORK,
    AV_CODEC_ID_PCM_S16LE_PLANAR,
    AV_CODEC_ID_PCM_DVD,
    AV_CODEC_ID_PCM_F32BE,
    AV_CODEC_ID_PCM_F32LE,
    AV_CODEC_ID_PCM_F64BE,
    AV_CODEC_ID_PCM_F64LE,
    AV_CODEC_ID_PCM_BLURAY,
    AV_CODEC_ID_PCM_LXF,
    AV_CODEC_ID_S302M,
    AV_CODEC_ID_PCM_S8_PLANAR,
    AV_CODEC_ID_PCM_S24LE_PLANAR,
    AV_CODEC_ID_PCM_S32LE_PLANAR,
    AV_CODEC_ID_PCM_S16BE_PLANAR,
    AV_CODEC_ID_PCM_S64LE,
    AV_CODEC_ID_PCM_S64BE,
    AV_CODEC_ID_PCM_F16LE,
    AV_CODEC_ID_PCM_F24LE,
    AV_CODEC_ID_PCM_VIDC,
    AV_CODEC_ID_ADPCM_IMA_QT,
    AV_CODEC_ID_ADPCM_IMA_WAV,
    AV_CODEC_ID_ADPCM_IMA_DK3,
    AV_CODEC_ID_ADPCM_IMA_DK4,
    AV_CODEC_ID_ADPCM_IMA_WS,
    AV_CODEC_ID_ADPCM_IMA_SMJPEG,
    AV_CODEC_ID_ADPCM_MS,
    AV_CODEC_ID_ADPCM_4XM,
    AV_CODEC_ID_ADPCM_XA,
    AV_CODEC_ID_ADPCM_ADX,
    AV_CODEC_ID_ADPCM_EA,
    AV_CODEC_ID_ADPCM_G726,
    AV_CODEC_ID_ADPCM_CT,
    AV_CODEC_ID_ADPCM_SWF,
    AV_CODEC_ID_ADPCM_YAMAHA,
    AV_CODEC_ID_ADPCM_SBPRO_4,
    AV_CODEC_ID_ADPCM_SBPRO_3,
    AV_CODEC_ID_ADPCM_SBPRO_2,
    AV_CODEC_ID_ADPCM_THP,
    AV_CODEC_ID_ADPCM_IMA_AMV,
    AV_CODEC_ID_ADPCM_EA_R1,
    AV_CODEC_ID_ADPCM_EA_R3,
    AV_CODEC_ID_ADPCM_EA_R2,
    AV_CODEC_ID_ADPCM_IMA_EA_SEAD,
    AV_CODEC_ID_ADPCM_IMA_EA_EACS,
    AV_CODEC_ID_ADPCM_EA_XAS,
    AV_CODEC_ID_ADPCM_EA_MAXIS_XA,
    AV_CODEC_ID_ADPCM_IMA_ISS,
    AV_CODEC_ID_ADPCM_G722,
    AV_CODEC_ID_ADPCM_IMA_APC,
    AV_CODEC_ID_ADPCM_VIMA,
    AV_CODEC_ID_ADPCM_AFC,
    AV_CODEC_ID_ADPCM_IMA_OKI,
    AV_CODEC_ID_ADPCM_DTK,
    AV_CODEC_ID_ADPCM_IMA_RAD,
    AV_CODEC_ID_ADPCM_G726LE,
    AV_CODEC_ID_ADPCM_THP_LE,
    AV_CODEC_ID_ADPCM_PSX,
    AV_CODEC_ID_ADPCM_AICA,
    AV_CODEC_ID_ADPCM_IMA_DAT4,
    AV_CODEC_ID_ADPCM_MTAF,
    AV_CODEC_ID_AMR_NB,
    AV_CODEC_ID_AMR_WB,
    AV_CODEC_ID_RA_144,
    AV_CODEC_ID_RA_288,
    AV_CODEC_ID_ROQ_DPCM,
    AV_CODEC_ID_INTERPLAY_DPCM,
    AV_CODEC_ID_XAN_DPCM,
    AV_CODEC_ID_SOL_DPCM,
    AV_CODEC_ID_SDX2_DPCM,
    AV_CODEC_ID_GREMLIN_DPCM,
    AV_CODEC_ID_MP2,
    AV_CODEC_ID_MP3,
    AV_CODEC_ID_AAC,
    AV_CODEC_ID_AC3,
    AV_CODEC_ID_DTS,
    AV_CODEC_ID_VORBIS,
    AV_CODEC_ID_DVAUDIO,
    AV_CODEC_ID_WMAV1,
    AV_CODEC_ID_WMAV2,
    AV_CODEC_ID_MACE3,
    AV_CODEC_ID_MACE6,
    AV_CODEC_ID_VMDAUDIO,
    AV_CODEC_ID_FLAC,
    AV_CODEC_ID_MP3ADU,
    AV_CODEC_ID_MP3ON4,
    AV_CODEC_ID_SHORTEN,
    AV_CODEC_ID_ALAC,
    AV_CODEC_ID_WESTWOOD_SND1,
    AV_CODEC_ID_GSM,
    AV_CODEC_ID_QDM2,
    AV_CODEC_ID_COOK,
    AV_CODEC_ID_TRUESPEECH,
    AV_CODEC_ID_TTA,
    AV_CODEC_ID_SMACKAUDIO,
    AV_CODEC_ID_QCELP,
    AV_CODEC_ID_WAVPACK,
    AV_CODEC_ID_DSICINAUDIO,
    AV_CODEC_ID_IMC,
    AV_CODEC_ID_MUSEPACK7,
    AV_CODEC_ID_MLP,
    AV_CODEC_ID_GSM_MS,
    AV_CODEC_ID_ATRAC3,
    AV_CODEC_ID_APE,
    AV_CODEC_ID_NELLYMOSER,
    AV_CODEC_ID_MUSEPACK8,
    AV_CODEC_ID_SPEEX,
    AV_CODEC_ID_WMAVOICE,
    AV_CODEC_ID_WMAPRO,
    AV_CODEC_ID_WMALOSSLESS,
    AV_CODEC_ID_ATRAC3P,
    AV_CODEC_ID_EAC3,
    AV_CODEC_ID_SIPR,
    AV_CODEC_ID_MP1,
    AV_CODEC_ID_TWINVQ,
    AV_CODEC_ID_TRUEHD,
    AV_CODEC_ID_MP4ALS,
    AV_CODEC_ID_ATRAC1,
    AV_CODEC_ID_BINKAUDIO_RDFT,
    AV_CODEC_ID_BINKAUDIO_DCT,
    AV_CODEC_ID_AAC_LATM,
    AV_CODEC_ID_QDMC,
    AV_CODEC_ID_CELT,
    AV_CODEC_ID_G723_1,
    AV_CODEC_ID_G729,
    AV_CODEC_ID_8SVX_EXP,
    AV_CODEC_ID_8SVX_FIB,
    AV_CODEC_ID_BMV_AUDIO,
    AV_CODEC_ID_RALF,
    AV_CODEC_ID_IAC,
    AV_CODEC_ID_ILBC,
    AV_CODEC_ID_OPUS,
    AV_CODEC_ID_COMFORT_NOISE,
    AV_CODEC_ID_TAK,
    AV_CODEC_ID_METASOUND,
    AV_CODEC_ID_PAF_AUDIO,
    AV_CODEC_ID_ON2AVC,
    AV_CODEC_ID_DSS_SP,
    AV_CODEC_ID_CODEC2,
    AV_CODEC_ID_FFWAVESYNTH,
    AV_CODEC_ID_SONIC,
    AV_CODEC_ID_SONIC_LS,
    AV_CODEC_ID_EVRC,
    AV_CODEC_ID_SMV,
    AV_CODEC_ID_DSD_LSBF,
    AV_CODEC_ID_DSD_MSBF,
    AV_CODEC_ID_DSD_LSBF_PLANAR,
    AV_CODEC_ID_DSD_MSBF_PLANAR,
    AV_CODEC_ID_4GV,
    AV_CODEC_ID_INTERPLAY_ACM,
    AV_CODEC_ID_XMA1,
    AV_CODEC_ID_XMA2,
    AV_CODEC_ID_DST,
    AV_CODEC_ID_ATRAC3AL,
    AV_CODEC_ID_ATRAC3PAL,
    AV_CODEC_ID_DOLBY_E,
    AV_CODEC_ID_APTX,
    AV_CODEC_ID_APTX_HD,
    AV_CODEC_ID_SBC,
    AV_CODEC_ID_ATRAC9,
    AV_CODEC_ID_FIRST_SUBTITLE,
    AV_CODEC_ID_DVD_SUBTITLE,
    AV_CODEC_ID_DVB_SUBTITLE,
    AV_CODEC_ID_TEXT,
    AV_CODEC_ID_XSUB,
    AV_CODEC_ID_SSA,
    AV_CODEC_ID_MOV_TEXT,
    AV_CODEC_ID_HDMV_PGS_SUBTITLE,
    AV_CODEC_ID_DVB_TELETEXT,
    AV_CODEC_ID_SRT,
    AV_CODEC_ID_MICRODVD,
    AV_CODEC_ID_EIA_608,
    AV_CODEC_ID_JACOSUB,
    AV_CODEC_ID_SAMI,
    AV_CODEC_ID_REALTEXT,
    AV_CODEC_ID_STL,
    AV_CODEC_ID_SUBVIEWER1,
    AV_CODEC_ID_SUBVIEWER,
    AV_CODEC_ID_SUBRIP,
    AV_CODEC_ID_WEBVTT,
    AV_CODEC_ID_MPL2,
    AV_CODEC_ID_VPLAYER,
    AV_CODEC_ID_PJS,
    AV_CODEC_ID_ASS,
    AV_CODEC_ID_HDMV_TEXT_SUBTITLE,
    AV_CODEC_ID_TTML,
    AV_CODEC_ID_FIRST_UNKNOWN,
    AV_CODEC_ID_TTF,
    AV_CODEC_ID_SCTE_35,
    AV_CODEC_ID_BINTEXT,
    AV_CODEC_ID_XBIN,
    AV_CODEC_ID_IDF,
    AV_CODEC_ID_OTF,
    AV_CODEC_ID_SMPTE_KLV,
    AV_CODEC_ID_DVD_NAV,
    AV_CODEC_ID_TIMED_ID3,
    AV_CODEC_ID_BIN_DATA,
    AV_CODEC_ID_PROBE,
    AV_CODEC_ID_MPEG2TS,
    AV_CODEC_ID_MPEG4SYSTEMS,
    AV_CODEC_ID_FFMETADATA,
    AV_CODEC_ID_WRAPPED_AVFRAME,
    AV_CODEC_ID_IFF_BYTERUN1,
    AV_CODEC_ID_H265,
    AV_CODEC_PROP_INTRA_ONLY,
    AV_CODEC_PROP_LOSSY,
    AV_CODEC_PROP_LOSSLESS,
    AV_CODEC_PROP_REORDER,
    AV_CODEC_PROP_BITMAP_SUB,
    AV_CODEC_PROP_TEXT_SUB,
    AV_INPUT_BUFFER_PADDING_SIZE,
    AV_INPUT_BUFFER_MIN_SIZE,
    AV_CODEC_FLAG_UNALIGNED,
    AV_CODEC_FLAG_QSCALE,
    AV_CODEC_FLAG_4MV,
    AV_CODEC_FLAG_OUTPUT_CORRUPT,
    AV_CODEC_FLAG_QPEL,
    AV_CODEC_FLAG_PASS1,
    AV_CODEC_FLAG_PASS2,
    AV_CODEC_FLAG_LOOP_FILTER,
    AV_CODEC_FLAG_GRAY,
    AV_CODEC_FLAG_PSNR,
    AV_CODEC_FLAG_TRUNCATED,
    AV_CODEC_FLAG_INTERLACED_DCT,
    AV_CODEC_FLAG_LOW_DELAY,
    AV_CODEC_FLAG_GLOBAL_HEADER,
    AV_CODEC_FLAG_BITEXACT,
    AV_CODEC_FLAG_AC_PRED,
    AV_CODEC_FLAG_INTERLACED_ME,
    AV_CODEC_FLAG_CLOSED_GOP,
    AV_CODEC_FLAG2_FAST,
    AV_CODEC_FLAG2_NO_OUTPUT,
    AV_CODEC_FLAG2_LOCAL_HEADER,
    AV_CODEC_FLAG2_DROP_FRAME_TIMECODE,
    AV_CODEC_FLAG2_CHUNKS,
    AV_CODEC_FLAG2_IGNORE_CROP,
    AV_CODEC_FLAG2_SHOW_ALL,
    AV_CODEC_FLAG2_EXPORT_MVS,
    AV_CODEC_FLAG2_SKIP_MANUAL,
    AV_CODEC_FLAG2_RO_FLUSH_NOOP,
    AV_CODEC_CAP_DRAW_HORIZ_BAND,
    AV_CODEC_CAP_DR1,
    AV_CODEC_CAP_TRUNCATED,
    AV_CODEC_CAP_DELAY,
    AV_CODEC_CAP_SMALL_LAST_FRAME,
    AV_CODEC_CAP_SUBFRAMES,
    AV_CODEC_CAP_EXPERIMENTAL,
    AV_CODEC_CAP_CHANNEL_CONF,
    AV_CODEC_CAP_FRAME_THREADS,
    AV_CODEC_CAP_SLICE_THREADS,
    AV_CODEC_CAP_PARAM_CHANGE,
    AV_CODEC_CAP_AUTO_THREADS,
    AV_CODEC_CAP_VARIABLE_FRAME_SIZE,
    AV_CODEC_CAP_AVOID_PROBING,
    AV_CODEC_CAP_INTRA_ONLY,
    AV_CODEC_CAP_LOSSLESS,
    AV_CODEC_CAP_HARDWARE,
    AV_CODEC_CAP_HYBRID,
    AV_GET_BUFFER_FLAG_REF,
    AVPacketSideDataType,
    AV_PKT_DATA_PALETTE,
    AV_PKT_DATA_NEW_EXTRADATA,
    AV_PKT_DATA_PARAM_CHANGE,
    AV_PKT_DATA_H263_MB_INFO,
    AV_PKT_DATA_REPLAYGAIN,
    AV_PKT_DATA_DISPLAYMATRIX,
    AV_PKT_DATA_STEREO3D,
    AV_PKT_DATA_AUDIO_SERVICE_TYPE,
    AV_PKT_DATA_QUALITY_STATS,
    AV_PKT_DATA_FALLBACK_TRACK,
    AV_PKT_DATA_CPB_PROPERTIES,
    AV_PKT_DATA_SKIP_SAMPLES,
    AV_PKT_DATA_JP_DUALMONO,
    AV_PKT_DATA_STRINGS_METADATA,
    AV_PKT_DATA_SUBTITLE_POSITION,
    AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL,
    AV_PKT_DATA_WEBVTT_IDENTIFIER,
    AV_PKT_DATA_WEBVTT_SETTINGS,
    AV_PKT_DATA_METADATA_UPDATE,
    AV_PKT_DATA_MPEGTS_STREAM_ID,
    AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
    AV_PKT_DATA_SPHERICAL,
    AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
    AV_PKT_DATA_A53_CC,
    AV_PKT_DATA_ENCRYPTION_INIT_INFO,
    AV_PKT_DATA_ENCRYPTION_INFO,
    AV_PKT_DATA_AFD,
    AV_PKT_DATA_NB,
    AV_PKT_DATA_QUALITY_FACTOR,
    AV_PKT_FLAG_KEY,
    AV_PKT_FLAG_CORRUPT,
    AV_PKT_FLAG_DISCARD,
    AV_PKT_FLAG_TRUSTED,
    AV_PKT_FLAG_DISPOSABLE,
    SLICE_FLAG_CODED_ORDER,
    SLICE_FLAG_ALLOW_FIELD,
    SLICE_FLAG_ALLOW_PLANE,
    AV_EF_CRCCHECK,
    AV_EF_BITSTREAM,
    AV_EF_BUFFER,
    AV_EF_EXPLODE,
    AV_EF_IGNORE_ERR,
    AV_EF_CAREFUL,
    AV_EF_COMPLIANT,
    AV_EF_AGGRESSIVE,
    AV_HWACCEL_CODEC_CAP_EXPERIMENTAL,
    AV_HWACCEL_FLAG_IGNORE_LEVEL,
    AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH,
    AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH,
    AV_SUBTITLE_FLAG_FORCED,
    AV_PARSER_PTS_NB,
    PARSER_FLAG_COMPLETE_FRAMES,
    PARSER_FLAG_ONCE,
    PARSER_FLAG_FETCHED_OFFSET,
    PARSER_FLAG_USE_CODEC_TS,
    AVProfile,
    AVCodecDescriptor,
    AVDiscard,
    AVDISCARD_NONE,
    AVDISCARD_DEFAULT,
    AVDISCARD_NONREF,
    AVDISCARD_BIDIR,
    AVDISCARD_NONINTRA,
    AVDISCARD_NONKEY,
    AVDISCARD_ALL,
    AVAudioServiceType,
    AV_AUDIO_SERVICE_TYPE_MAIN,
    AV_AUDIO_SERVICE_TYPE_EFFECTS,
    AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED,
    AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED,
    AV_AUDIO_SERVICE_TYPE_DIALOGUE,
    AV_AUDIO_SERVICE_TYPE_COMMENTARY,
    AV_AUDIO_SERVICE_TYPE_EMERGENCY,
    AV_AUDIO_SERVICE_TYPE_VOICE_OVER,
    AV_AUDIO_SERVICE_TYPE_KARAOKE,
    AV_AUDIO_SERVICE_TYPE_NB,
    RcOverride,
    AVPanScan,
    AVCPBProperties,
    AVPacketSideData,
    AVPacket,
    AVSideDataParamChangeFlags,
    AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT,
    AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT,
    AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE,
    AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS,
    AVCodecInternal,
    AVFieldOrder,
    AV_FIELD_UNKNOWN,
    AV_FIELD_PROGRESSIVE,
    AV_FIELD_TT,
    AV_FIELD_BB,
    AV_FIELD_TB,
    AV_FIELD_BT,
    AVCodecDefault,
    AVCodec,
    AVHWAccel,
    AVFrame,
    AVCodecContext,
    ANONYMOUS_1,
    AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX,
    AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX,
    AV_CODEC_HW_CONFIG_METHOD_INTERNAL,
    AV_CODEC_HW_CONFIG_METHOD_AD_HOC,
    AVCodecHWConfig,
    AVPicture,
    AVSubtitleType,
    SUBTITLE_NONE,
    SUBTITLE_BITMAP,
    SUBTITLE_TEXT,
    SUBTITLE_ASS,
    AVSubtitleRect,
    AVSubtitle,
    MpegEncContext,
    AVCodecParameters,
    AVPictureStructure,
    AV_PICTURE_STRUCTURE_UNKNOWN,
    AV_PICTURE_STRUCTURE_TOP_FIELD,
    AV_PICTURE_STRUCTURE_BOTTOM_FIELD,
    AV_PICTURE_STRUCTURE_FRAME,
    AVCodecParser,
    AVCodecParserContext,
    AVBitStreamFilter,
    AVBitStreamFilterContext,
    AVBSFInternal,
    AVBSFContext,
    AVBSFList,
    AVLockOp,
    AV_LOCK_CREATE,
    AV_LOCK_OBTAIN,
    AV_LOCK_RELEASE,
    AV_LOCK_DESTROY,
    LIBAVCODEC_VERSION_MAJOR,
    LIBAVCODEC_VERSION_MINOR,
    LIBAVCODEC_VERSION_MICRO,
    # LIBAVCODEC_BUILD,
    AV_AAC_ADTS_HEADER_SIZE,
    AVDCT,
    AVD3D11VAContext,
    MAX_DWT_LEVELS,
    DiracParseCodes,
    DIRAC_PCODE_SEQ_HEADER,
    DIRAC_PCODE_END_SEQ,
    DIRAC_PCODE_AUX,
    DIRAC_PCODE_PAD,
    DIRAC_PCODE_PICTURE_CODED,
    DIRAC_PCODE_PICTURE_RAW,
    DIRAC_PCODE_PICTURE_LOW_DEL,
    DIRAC_PCODE_PICTURE_HQ,
    DIRAC_PCODE_INTER_NOREF_CO1,
    DIRAC_PCODE_INTER_NOREF_CO2,
    DIRAC_PCODE_INTER_REF_CO1,
    DIRAC_PCODE_INTER_REF_CO2,
    DIRAC_PCODE_INTRA_REF_CO,
    DIRAC_PCODE_INTRA_REF_RAW,
    DIRAC_PCODE_INTRA_REF_PICT,
    DIRAC_PCODE_MAGIC,
    DiracVersionInfo,
    AVDiracSeqHeader,
    DV_PROFILE_BYTES,
    AVDVProfile,
    AVMediaCodecContext,
    MediaCodecBuffer,
    AVMediaCodecBuffer,
    AVQSVContext,
    # AVVDPAU_Render2,
    # AVVDPAUContext,
    # Picture,
    AVVideotoolboxContext,
    VORBIS_FLAG_HEADER,
    VORBIS_FLAG_COMMENT,
    VORBIS_FLAG_SETUP,
    AVVorbisParseContext,
    AV_XVMC_ID

const unix = 1
const linux = 1

# begin enum AVCodecID
const AVCodecID = UInt32
const AV_CODEC_ID_NONE = 0 |> UInt32
const AV_CODEC_ID_MPEG1VIDEO = 1 |> UInt32
const AV_CODEC_ID_MPEG2VIDEO = 2 |> UInt32
const AV_CODEC_ID_H261 = 3 |> UInt32
const AV_CODEC_ID_H263 = 4 |> UInt32
const AV_CODEC_ID_RV10 = 5 |> UInt32
const AV_CODEC_ID_RV20 = 6 |> UInt32
const AV_CODEC_ID_MJPEG = 7 |> UInt32
const AV_CODEC_ID_MJPEGB = 8 |> UInt32
const AV_CODEC_ID_LJPEG = 9 |> UInt32
const AV_CODEC_ID_SP5X = 10 |> UInt32
const AV_CODEC_ID_JPEGLS = 11 |> UInt32
const AV_CODEC_ID_MPEG4 = 12 |> UInt32
const AV_CODEC_ID_RAWVIDEO = 13 |> UInt32
const AV_CODEC_ID_MSMPEG4V1 = 14 |> UInt32
const AV_CODEC_ID_MSMPEG4V2 = 15 |> UInt32
const AV_CODEC_ID_MSMPEG4V3 = 16 |> UInt32
const AV_CODEC_ID_WMV1 = 17 |> UInt32
const AV_CODEC_ID_WMV2 = 18 |> UInt32
const AV_CODEC_ID_H263P = 19 |> UInt32
const AV_CODEC_ID_H263I = 20 |> UInt32
const AV_CODEC_ID_FLV1 = 21 |> UInt32
const AV_CODEC_ID_SVQ1 = 22 |> UInt32
const AV_CODEC_ID_SVQ3 = 23 |> UInt32
const AV_CODEC_ID_DVVIDEO = 24 |> UInt32
const AV_CODEC_ID_HUFFYUV = 25 |> UInt32
const AV_CODEC_ID_CYUV = 26 |> UInt32
const AV_CODEC_ID_H264 = 27 |> UInt32
const AV_CODEC_ID_INDEO3 = 28 |> UInt32
const AV_CODEC_ID_VP3 = 29 |> UInt32
const AV_CODEC_ID_THEORA = 30 |> UInt32
const AV_CODEC_ID_ASV1 = 31 |> UInt32
const AV_CODEC_ID_ASV2 = 32 |> UInt32
const AV_CODEC_ID_FFV1 = 33 |> UInt32
const AV_CODEC_ID_4XM = 34 |> UInt32
const AV_CODEC_ID_VCR1 = 35 |> UInt32
const AV_CODEC_ID_CLJR = 36 |> UInt32
const AV_CODEC_ID_MDEC = 37 |> UInt32
const AV_CODEC_ID_ROQ = 38 |> UInt32
const AV_CODEC_ID_INTERPLAY_VIDEO = 39 |> UInt32
const AV_CODEC_ID_XAN_WC3 = 40 |> UInt32
const AV_CODEC_ID_XAN_WC4 = 41 |> UInt32
const AV_CODEC_ID_RPZA = 42 |> UInt32
const AV_CODEC_ID_CINEPAK = 43 |> UInt32
const AV_CODEC_ID_WS_VQA = 44 |> UInt32
const AV_CODEC_ID_MSRLE = 45 |> UInt32
const AV_CODEC_ID_MSVIDEO1 = 46 |> UInt32
const AV_CODEC_ID_IDCIN = 47 |> UInt32
const AV_CODEC_ID_8BPS = 48 |> UInt32
const AV_CODEC_ID_SMC = 49 |> UInt32
const AV_CODEC_ID_FLIC = 50 |> UInt32
const AV_CODEC_ID_TRUEMOTION1 = 51 |> UInt32
const AV_CODEC_ID_VMDVIDEO = 52 |> UInt32
const AV_CODEC_ID_MSZH = 53 |> UInt32
const AV_CODEC_ID_ZLIB = 54 |> UInt32
const AV_CODEC_ID_QTRLE = 55 |> UInt32
const AV_CODEC_ID_TSCC = 56 |> UInt32
const AV_CODEC_ID_ULTI = 57 |> UInt32
const AV_CODEC_ID_QDRAW = 58 |> UInt32
const AV_CODEC_ID_VIXL = 59 |> UInt32
const AV_CODEC_ID_QPEG = 60 |> UInt32
const AV_CODEC_ID_PNG = 61 |> UInt32
const AV_CODEC_ID_PPM = 62 |> UInt32
const AV_CODEC_ID_PBM = 63 |> UInt32
const AV_CODEC_ID_PGM = 64 |> UInt32
const AV_CODEC_ID_PGMYUV = 65 |> UInt32
const AV_CODEC_ID_PAM = 66 |> UInt32
const AV_CODEC_ID_FFVHUFF = 67 |> UInt32
const AV_CODEC_ID_RV30 = 68 |> UInt32
const AV_CODEC_ID_RV40 = 69 |> UInt32
const AV_CODEC_ID_VC1 = 70 |> UInt32
const AV_CODEC_ID_WMV3 = 71 |> UInt32
const AV_CODEC_ID_LOCO = 72 |> UInt32
const AV_CODEC_ID_WNV1 = 73 |> UInt32
const AV_CODEC_ID_AASC = 74 |> UInt32
const AV_CODEC_ID_INDEO2 = 75 |> UInt32
const AV_CODEC_ID_FRAPS = 76 |> UInt32
const AV_CODEC_ID_TRUEMOTION2 = 77 |> UInt32
const AV_CODEC_ID_BMP = 78 |> UInt32
const AV_CODEC_ID_CSCD = 79 |> UInt32
const AV_CODEC_ID_MMVIDEO = 80 |> UInt32
const AV_CODEC_ID_ZMBV = 81 |> UInt32
const AV_CODEC_ID_AVS = 82 |> UInt32
const AV_CODEC_ID_SMACKVIDEO = 83 |> UInt32
const AV_CODEC_ID_NUV = 84 |> UInt32
const AV_CODEC_ID_KMVC = 85 |> UInt32
const AV_CODEC_ID_FLASHSV = 86 |> UInt32
const AV_CODEC_ID_CAVS = 87 |> UInt32
const AV_CODEC_ID_JPEG2000 = 88 |> UInt32
const AV_CODEC_ID_VMNC = 89 |> UInt32
const AV_CODEC_ID_VP5 = 90 |> UInt32
const AV_CODEC_ID_VP6 = 91 |> UInt32
const AV_CODEC_ID_VP6F = 92 |> UInt32
const AV_CODEC_ID_TARGA = 93 |> UInt32
const AV_CODEC_ID_DSICINVIDEO = 94 |> UInt32
const AV_CODEC_ID_TIERTEXSEQVIDEO = 95 |> UInt32
const AV_CODEC_ID_TIFF = 96 |> UInt32
const AV_CODEC_ID_GIF = 97 |> UInt32
const AV_CODEC_ID_DXA = 98 |> UInt32
const AV_CODEC_ID_DNXHD = 99 |> UInt32
const AV_CODEC_ID_THP = 100 |> UInt32
const AV_CODEC_ID_SGI = 101 |> UInt32
const AV_CODEC_ID_C93 = 102 |> UInt32
const AV_CODEC_ID_BETHSOFTVID = 103 |> UInt32
const AV_CODEC_ID_PTX = 104 |> UInt32
const AV_CODEC_ID_TXD = 105 |> UInt32
const AV_CODEC_ID_VP6A = 106 |> UInt32
const AV_CODEC_ID_AMV = 107 |> UInt32
const AV_CODEC_ID_VB = 108 |> UInt32
const AV_CODEC_ID_PCX = 109 |> UInt32
const AV_CODEC_ID_SUNRAST = 110 |> UInt32
const AV_CODEC_ID_INDEO4 = 111 |> UInt32
const AV_CODEC_ID_INDEO5 = 112 |> UInt32
const AV_CODEC_ID_MIMIC = 113 |> UInt32
const AV_CODEC_ID_RL2 = 114 |> UInt32
const AV_CODEC_ID_ESCAPE124 = 115 |> UInt32
const AV_CODEC_ID_DIRAC = 116 |> UInt32
const AV_CODEC_ID_BFI = 117 |> UInt32
const AV_CODEC_ID_CMV = 118 |> UInt32
const AV_CODEC_ID_MOTIONPIXELS = 119 |> UInt32
const AV_CODEC_ID_TGV = 120 |> UInt32
const AV_CODEC_ID_TGQ = 121 |> UInt32
const AV_CODEC_ID_TQI = 122 |> UInt32
const AV_CODEC_ID_AURA = 123 |> UInt32
const AV_CODEC_ID_AURA2 = 124 |> UInt32
const AV_CODEC_ID_V210X = 125 |> UInt32
const AV_CODEC_ID_TMV = 126 |> UInt32
const AV_CODEC_ID_V210 = 127 |> UInt32
const AV_CODEC_ID_DPX = 128 |> UInt32
const AV_CODEC_ID_MAD = 129 |> UInt32
const AV_CODEC_ID_FRWU = 130 |> UInt32
const AV_CODEC_ID_FLASHSV2 = 131 |> UInt32
const AV_CODEC_ID_CDGRAPHICS = 132 |> UInt32
const AV_CODEC_ID_R210 = 133 |> UInt32
const AV_CODEC_ID_ANM = 134 |> UInt32
const AV_CODEC_ID_BINKVIDEO = 135 |> UInt32
const AV_CODEC_ID_IFF_ILBM = 136 |> UInt32
const AV_CODEC_ID_KGV1 = 137 |> UInt32
const AV_CODEC_ID_YOP = 138 |> UInt32
const AV_CODEC_ID_VP8 = 139 |> UInt32
const AV_CODEC_ID_PICTOR = 140 |> UInt32
const AV_CODEC_ID_ANSI = 141 |> UInt32
const AV_CODEC_ID_A64_MULTI = 142 |> UInt32
const AV_CODEC_ID_A64_MULTI5 = 143 |> UInt32
const AV_CODEC_ID_R10K = 144 |> UInt32
const AV_CODEC_ID_MXPEG = 145 |> UInt32
const AV_CODEC_ID_LAGARITH = 146 |> UInt32
const AV_CODEC_ID_PRORES = 147 |> UInt32
const AV_CODEC_ID_JV = 148 |> UInt32
const AV_CODEC_ID_DFA = 149 |> UInt32
const AV_CODEC_ID_WMV3IMAGE = 150 |> UInt32
const AV_CODEC_ID_VC1IMAGE = 151 |> UInt32
const AV_CODEC_ID_UTVIDEO = 152 |> UInt32
const AV_CODEC_ID_BMV_VIDEO = 153 |> UInt32
const AV_CODEC_ID_VBLE = 154 |> UInt32
const AV_CODEC_ID_DXTORY = 155 |> UInt32
const AV_CODEC_ID_V410 = 156 |> UInt32
const AV_CODEC_ID_XWD = 157 |> UInt32
const AV_CODEC_ID_CDXL = 158 |> UInt32
const AV_CODEC_ID_XBM = 159 |> UInt32
const AV_CODEC_ID_ZEROCODEC = 160 |> UInt32
const AV_CODEC_ID_MSS1 = 161 |> UInt32
const AV_CODEC_ID_MSA1 = 162 |> UInt32
const AV_CODEC_ID_TSCC2 = 163 |> UInt32
const AV_CODEC_ID_MTS2 = 164 |> UInt32
const AV_CODEC_ID_CLLC = 165 |> UInt32
const AV_CODEC_ID_MSS2 = 166 |> UInt32
const AV_CODEC_ID_VP9 = 167 |> UInt32
const AV_CODEC_ID_AIC = 168 |> UInt32
const AV_CODEC_ID_ESCAPE130 = 169 |> UInt32
const AV_CODEC_ID_G2M = 170 |> UInt32
const AV_CODEC_ID_WEBP = 171 |> UInt32
const AV_CODEC_ID_HNM4_VIDEO = 172 |> UInt32
const AV_CODEC_ID_HEVC = 173 |> UInt32
const AV_CODEC_ID_FIC = 174 |> UInt32
const AV_CODEC_ID_ALIAS_PIX = 175 |> UInt32
const AV_CODEC_ID_BRENDER_PIX = 176 |> UInt32
const AV_CODEC_ID_PAF_VIDEO = 177 |> UInt32
const AV_CODEC_ID_EXR = 178 |> UInt32
const AV_CODEC_ID_VP7 = 179 |> UInt32
const AV_CODEC_ID_SANM = 180 |> UInt32
const AV_CODEC_ID_SGIRLE = 181 |> UInt32
const AV_CODEC_ID_MVC1 = 182 |> UInt32
const AV_CODEC_ID_MVC2 = 183 |> UInt32
const AV_CODEC_ID_HQX = 184 |> UInt32
const AV_CODEC_ID_TDSC = 185 |> UInt32
const AV_CODEC_ID_HQ_HQA = 186 |> UInt32
const AV_CODEC_ID_HAP = 187 |> UInt32
const AV_CODEC_ID_DDS = 188 |> UInt32
const AV_CODEC_ID_DXV = 189 |> UInt32
const AV_CODEC_ID_SCREENPRESSO = 190 |> UInt32
const AV_CODEC_ID_RSCC = 191 |> UInt32
const AV_CODEC_ID_AVS2 = 192 |> UInt32
const AV_CODEC_ID_Y41P = 32768 |> UInt32
const AV_CODEC_ID_AVRP = 32769 |> UInt32
const AV_CODEC_ID_012V = 32770 |> UInt32
const AV_CODEC_ID_AVUI = 32771 |> UInt32
const AV_CODEC_ID_AYUV = 32772 |> UInt32
const AV_CODEC_ID_TARGA_Y216 = 32773 |> UInt32
const AV_CODEC_ID_V308 = 32774 |> UInt32
const AV_CODEC_ID_V408 = 32775 |> UInt32
const AV_CODEC_ID_YUV4 = 32776 |> UInt32
const AV_CODEC_ID_AVRN = 32777 |> UInt32
const AV_CODEC_ID_CPIA = 32778 |> UInt32
const AV_CODEC_ID_XFACE = 32779 |> UInt32
const AV_CODEC_ID_SNOW = 32780 |> UInt32
const AV_CODEC_ID_SMVJPEG = 32781 |> UInt32
const AV_CODEC_ID_APNG = 32782 |> UInt32
const AV_CODEC_ID_DAALA = 32783 |> UInt32
const AV_CODEC_ID_CFHD = 32784 |> UInt32
const AV_CODEC_ID_TRUEMOTION2RT = 32785 |> UInt32
const AV_CODEC_ID_M101 = 32786 |> UInt32
const AV_CODEC_ID_MAGICYUV = 32787 |> UInt32
const AV_CODEC_ID_SHEERVIDEO = 32788 |> UInt32
const AV_CODEC_ID_YLC = 32789 |> UInt32
const AV_CODEC_ID_PSD = 32790 |> UInt32
const AV_CODEC_ID_PIXLET = 32791 |> UInt32
const AV_CODEC_ID_SPEEDHQ = 32792 |> UInt32
const AV_CODEC_ID_FMVC = 32793 |> UInt32
const AV_CODEC_ID_SCPR = 32794 |> UInt32
const AV_CODEC_ID_CLEARVIDEO = 32795 |> UInt32
const AV_CODEC_ID_XPM = 32796 |> UInt32
const AV_CODEC_ID_AV1 = 32797 |> UInt32
const AV_CODEC_ID_BITPACKED = 32798 |> UInt32
const AV_CODEC_ID_MSCC = 32799 |> UInt32
const AV_CODEC_ID_SRGC = 32800 |> UInt32
const AV_CODEC_ID_SVG = 32801 |> UInt32
const AV_CODEC_ID_GDV = 32802 |> UInt32
const AV_CODEC_ID_FITS = 32803 |> UInt32
const AV_CODEC_ID_IMM4 = 32804 |> UInt32
const AV_CODEC_ID_PROSUMER = 32805 |> UInt32
const AV_CODEC_ID_MWSC = 32806 |> UInt32
const AV_CODEC_ID_WCMV = 32807 |> UInt32
const AV_CODEC_ID_RASC = 32808 |> UInt32
const AV_CODEC_ID_FIRST_AUDIO = 65536 |> UInt32
const AV_CODEC_ID_PCM_S16LE = 65536 |> UInt32
const AV_CODEC_ID_PCM_S16BE = 65537 |> UInt32
const AV_CODEC_ID_PCM_U16LE = 65538 |> UInt32
const AV_CODEC_ID_PCM_U16BE = 65539 |> UInt32
const AV_CODEC_ID_PCM_S8 = 65540 |> UInt32
const AV_CODEC_ID_PCM_U8 = 65541 |> UInt32
const AV_CODEC_ID_PCM_MULAW = 65542 |> UInt32
const AV_CODEC_ID_PCM_ALAW = 65543 |> UInt32
const AV_CODEC_ID_PCM_S32LE = 65544 |> UInt32
const AV_CODEC_ID_PCM_S32BE = 65545 |> UInt32
const AV_CODEC_ID_PCM_U32LE = 65546 |> UInt32
const AV_CODEC_ID_PCM_U32BE = 65547 |> UInt32
const AV_CODEC_ID_PCM_S24LE = 65548 |> UInt32
const AV_CODEC_ID_PCM_S24BE = 65549 |> UInt32
const AV_CODEC_ID_PCM_U24LE = 65550 |> UInt32
const AV_CODEC_ID_PCM_U24BE = 65551 |> UInt32
const AV_CODEC_ID_PCM_S24DAUD = 65552 |> UInt32
const AV_CODEC_ID_PCM_ZORK = 65553 |> UInt32
const AV_CODEC_ID_PCM_S16LE_PLANAR = 65554 |> UInt32
const AV_CODEC_ID_PCM_DVD = 65555 |> UInt32
const AV_CODEC_ID_PCM_F32BE = 65556 |> UInt32
const AV_CODEC_ID_PCM_F32LE = 65557 |> UInt32
const AV_CODEC_ID_PCM_F64BE = 65558 |> UInt32
const AV_CODEC_ID_PCM_F64LE = 65559 |> UInt32
const AV_CODEC_ID_PCM_BLURAY = 65560 |> UInt32
const AV_CODEC_ID_PCM_LXF = 65561 |> UInt32
const AV_CODEC_ID_S302M = 65562 |> UInt32
const AV_CODEC_ID_PCM_S8_PLANAR = 65563 |> UInt32
const AV_CODEC_ID_PCM_S24LE_PLANAR = 65564 |> UInt32
const AV_CODEC_ID_PCM_S32LE_PLANAR = 65565 |> UInt32
const AV_CODEC_ID_PCM_S16BE_PLANAR = 65566 |> UInt32
const AV_CODEC_ID_PCM_S64LE = 67584 |> UInt32
const AV_CODEC_ID_PCM_S64BE = 67585 |> UInt32
const AV_CODEC_ID_PCM_F16LE = 67586 |> UInt32
const AV_CODEC_ID_PCM_F24LE = 67587 |> UInt32
const AV_CODEC_ID_PCM_VIDC = 67588 |> UInt32
const AV_CODEC_ID_ADPCM_IMA_QT = 69632 |> UInt32
const AV_CODEC_ID_ADPCM_IMA_WAV = 69633 |> UInt32
const AV_CODEC_ID_ADPCM_IMA_DK3 = 69634 |> UInt32
const AV_CODEC_ID_ADPCM_IMA_DK4 = 69635 |> UInt32
const AV_CODEC_ID_ADPCM_IMA_WS = 69636 |> UInt32
const AV_CODEC_ID_ADPCM_IMA_SMJPEG = 69637 |> UInt32
const AV_CODEC_ID_ADPCM_MS = 69638 |> UInt32
const AV_CODEC_ID_ADPCM_4XM = 69639 |> UInt32
const AV_CODEC_ID_ADPCM_XA = 69640 |> UInt32
const AV_CODEC_ID_ADPCM_ADX = 69641 |> UInt32
const AV_CODEC_ID_ADPCM_EA = 69642 |> UInt32
const AV_CODEC_ID_ADPCM_G726 = 69643 |> UInt32
const AV_CODEC_ID_ADPCM_CT = 69644 |> UInt32
const AV_CODEC_ID_ADPCM_SWF = 69645 |> UInt32
const AV_CODEC_ID_ADPCM_YAMAHA = 69646 |> UInt32
const AV_CODEC_ID_ADPCM_SBPRO_4 = 69647 |> UInt32
const AV_CODEC_ID_ADPCM_SBPRO_3 = 69648 |> UInt32
const AV_CODEC_ID_ADPCM_SBPRO_2 = 69649 |> UInt32
const AV_CODEC_ID_ADPCM_THP = 69650 |> UInt32
const AV_CODEC_ID_ADPCM_IMA_AMV = 69651 |> UInt32
const AV_CODEC_ID_ADPCM_EA_R1 = 69652 |> UInt32
const AV_CODEC_ID_ADPCM_EA_R3 = 69653 |> UInt32
const AV_CODEC_ID_ADPCM_EA_R2 = 69654 |> UInt32
const AV_CODEC_ID_ADPCM_IMA_EA_SEAD = 69655 |> UInt32
const AV_CODEC_ID_ADPCM_IMA_EA_EACS = 69656 |> UInt32
const AV_CODEC_ID_ADPCM_EA_XAS = 69657 |> UInt32
const AV_CODEC_ID_ADPCM_EA_MAXIS_XA = 69658 |> UInt32
const AV_CODEC_ID_ADPCM_IMA_ISS = 69659 |> UInt32
const AV_CODEC_ID_ADPCM_G722 = 69660 |> UInt32
const AV_CODEC_ID_ADPCM_IMA_APC = 69661 |> UInt32
const AV_CODEC_ID_ADPCM_VIMA = 69662 |> UInt32
const AV_CODEC_ID_ADPCM_AFC = 71680 |> UInt32
const AV_CODEC_ID_ADPCM_IMA_OKI = 71681 |> UInt32
const AV_CODEC_ID_ADPCM_DTK = 71682 |> UInt32
const AV_CODEC_ID_ADPCM_IMA_RAD = 71683 |> UInt32
const AV_CODEC_ID_ADPCM_G726LE = 71684 |> UInt32
const AV_CODEC_ID_ADPCM_THP_LE = 71685 |> UInt32
const AV_CODEC_ID_ADPCM_PSX = 71686 |> UInt32
const AV_CODEC_ID_ADPCM_AICA = 71687 |> UInt32
const AV_CODEC_ID_ADPCM_IMA_DAT4 = 71688 |> UInt32
const AV_CODEC_ID_ADPCM_MTAF = 71689 |> UInt32
const AV_CODEC_ID_AMR_NB = 73728 |> UInt32
const AV_CODEC_ID_AMR_WB = 73729 |> UInt32
const AV_CODEC_ID_RA_144 = 77824 |> UInt32
const AV_CODEC_ID_RA_288 = 77825 |> UInt32
const AV_CODEC_ID_ROQ_DPCM = 81920 |> UInt32
const AV_CODEC_ID_INTERPLAY_DPCM = 81921 |> UInt32
const AV_CODEC_ID_XAN_DPCM = 81922 |> UInt32
const AV_CODEC_ID_SOL_DPCM = 81923 |> UInt32
const AV_CODEC_ID_SDX2_DPCM = 83968 |> UInt32
const AV_CODEC_ID_GREMLIN_DPCM = 83969 |> UInt32
const AV_CODEC_ID_MP2 = 86016 |> UInt32
const AV_CODEC_ID_MP3 = 86017 |> UInt32
const AV_CODEC_ID_AAC = 86018 |> UInt32
const AV_CODEC_ID_AC3 = 86019 |> UInt32
const AV_CODEC_ID_DTS = 86020 |> UInt32
const AV_CODEC_ID_VORBIS = 86021 |> UInt32
const AV_CODEC_ID_DVAUDIO = 86022 |> UInt32
const AV_CODEC_ID_WMAV1 = 86023 |> UInt32
const AV_CODEC_ID_WMAV2 = 86024 |> UInt32
const AV_CODEC_ID_MACE3 = 86025 |> UInt32
const AV_CODEC_ID_MACE6 = 86026 |> UInt32
const AV_CODEC_ID_VMDAUDIO = 86027 |> UInt32
const AV_CODEC_ID_FLAC = 86028 |> UInt32
const AV_CODEC_ID_MP3ADU = 86029 |> UInt32
const AV_CODEC_ID_MP3ON4 = 86030 |> UInt32
const AV_CODEC_ID_SHORTEN = 86031 |> UInt32
const AV_CODEC_ID_ALAC = 86032 |> UInt32
const AV_CODEC_ID_WESTWOOD_SND1 = 86033 |> UInt32
const AV_CODEC_ID_GSM = 86034 |> UInt32
const AV_CODEC_ID_QDM2 = 86035 |> UInt32
const AV_CODEC_ID_COOK = 86036 |> UInt32
const AV_CODEC_ID_TRUESPEECH = 86037 |> UInt32
const AV_CODEC_ID_TTA = 86038 |> UInt32
const AV_CODEC_ID_SMACKAUDIO = 86039 |> UInt32
const AV_CODEC_ID_QCELP = 86040 |> UInt32
const AV_CODEC_ID_WAVPACK = 86041 |> UInt32
const AV_CODEC_ID_DSICINAUDIO = 86042 |> UInt32
const AV_CODEC_ID_IMC = 86043 |> UInt32
const AV_CODEC_ID_MUSEPACK7 = 86044 |> UInt32
const AV_CODEC_ID_MLP = 86045 |> UInt32
const AV_CODEC_ID_GSM_MS = 86046 |> UInt32
const AV_CODEC_ID_ATRAC3 = 86047 |> UInt32
const AV_CODEC_ID_APE = 86048 |> UInt32
const AV_CODEC_ID_NELLYMOSER = 86049 |> UInt32
const AV_CODEC_ID_MUSEPACK8 = 86050 |> UInt32
const AV_CODEC_ID_SPEEX = 86051 |> UInt32
const AV_CODEC_ID_WMAVOICE = 86052 |> UInt32
const AV_CODEC_ID_WMAPRO = 86053 |> UInt32
const AV_CODEC_ID_WMALOSSLESS = 86054 |> UInt32
const AV_CODEC_ID_ATRAC3P = 86055 |> UInt32
const AV_CODEC_ID_EAC3 = 86056 |> UInt32
const AV_CODEC_ID_SIPR = 86057 |> UInt32
const AV_CODEC_ID_MP1 = 86058 |> UInt32
const AV_CODEC_ID_TWINVQ = 86059 |> UInt32
const AV_CODEC_ID_TRUEHD = 86060 |> UInt32
const AV_CODEC_ID_MP4ALS = 86061 |> UInt32
const AV_CODEC_ID_ATRAC1 = 86062 |> UInt32
const AV_CODEC_ID_BINKAUDIO_RDFT = 86063 |> UInt32
const AV_CODEC_ID_BINKAUDIO_DCT = 86064 |> UInt32
const AV_CODEC_ID_AAC_LATM = 86065 |> UInt32
const AV_CODEC_ID_QDMC = 86066 |> UInt32
const AV_CODEC_ID_CELT = 86067 |> UInt32
const AV_CODEC_ID_G723_1 = 86068 |> UInt32
const AV_CODEC_ID_G729 = 86069 |> UInt32
const AV_CODEC_ID_8SVX_EXP = 86070 |> UInt32
const AV_CODEC_ID_8SVX_FIB = 86071 |> UInt32
const AV_CODEC_ID_BMV_AUDIO = 86072 |> UInt32
const AV_CODEC_ID_RALF = 86073 |> UInt32
const AV_CODEC_ID_IAC = 86074 |> UInt32
const AV_CODEC_ID_ILBC = 86075 |> UInt32
const AV_CODEC_ID_OPUS = 86076 |> UInt32
const AV_CODEC_ID_COMFORT_NOISE = 86077 |> UInt32
const AV_CODEC_ID_TAK = 86078 |> UInt32
const AV_CODEC_ID_METASOUND = 86079 |> UInt32
const AV_CODEC_ID_PAF_AUDIO = 86080 |> UInt32
const AV_CODEC_ID_ON2AVC = 86081 |> UInt32
const AV_CODEC_ID_DSS_SP = 86082 |> UInt32
const AV_CODEC_ID_CODEC2 = 86083 |> UInt32
const AV_CODEC_ID_FFWAVESYNTH = 88064 |> UInt32
const AV_CODEC_ID_SONIC = 88065 |> UInt32
const AV_CODEC_ID_SONIC_LS = 88066 |> UInt32
const AV_CODEC_ID_EVRC = 88067 |> UInt32
const AV_CODEC_ID_SMV = 88068 |> UInt32
const AV_CODEC_ID_DSD_LSBF = 88069 |> UInt32
const AV_CODEC_ID_DSD_MSBF = 88070 |> UInt32
const AV_CODEC_ID_DSD_LSBF_PLANAR = 88071 |> UInt32
const AV_CODEC_ID_DSD_MSBF_PLANAR = 88072 |> UInt32
const AV_CODEC_ID_4GV = 88073 |> UInt32
const AV_CODEC_ID_INTERPLAY_ACM = 88074 |> UInt32
const AV_CODEC_ID_XMA1 = 88075 |> UInt32
const AV_CODEC_ID_XMA2 = 88076 |> UInt32
const AV_CODEC_ID_DST = 88077 |> UInt32
const AV_CODEC_ID_ATRAC3AL = 88078 |> UInt32
const AV_CODEC_ID_ATRAC3PAL = 88079 |> UInt32
const AV_CODEC_ID_DOLBY_E = 88080 |> UInt32
const AV_CODEC_ID_APTX = 88081 |> UInt32
const AV_CODEC_ID_APTX_HD = 88082 |> UInt32
const AV_CODEC_ID_SBC = 88083 |> UInt32
const AV_CODEC_ID_ATRAC9 = 88084 |> UInt32
const AV_CODEC_ID_FIRST_SUBTITLE = 94208 |> UInt32
const AV_CODEC_ID_DVD_SUBTITLE = 94208 |> UInt32
const AV_CODEC_ID_DVB_SUBTITLE = 94209 |> UInt32
const AV_CODEC_ID_TEXT = 94210 |> UInt32
const AV_CODEC_ID_XSUB = 94211 |> UInt32
const AV_CODEC_ID_SSA = 94212 |> UInt32
const AV_CODEC_ID_MOV_TEXT = 94213 |> UInt32
const AV_CODEC_ID_HDMV_PGS_SUBTITLE = 94214 |> UInt32
const AV_CODEC_ID_DVB_TELETEXT = 94215 |> UInt32
const AV_CODEC_ID_SRT = 94216 |> UInt32
const AV_CODEC_ID_MICRODVD = 96256 |> UInt32
const AV_CODEC_ID_EIA_608 = 96257 |> UInt32
const AV_CODEC_ID_JACOSUB = 96258 |> UInt32
const AV_CODEC_ID_SAMI = 96259 |> UInt32
const AV_CODEC_ID_REALTEXT = 96260 |> UInt32
const AV_CODEC_ID_STL = 96261 |> UInt32
const AV_CODEC_ID_SUBVIEWER1 = 96262 |> UInt32
const AV_CODEC_ID_SUBVIEWER = 96263 |> UInt32
const AV_CODEC_ID_SUBRIP = 96264 |> UInt32
const AV_CODEC_ID_WEBVTT = 96265 |> UInt32
const AV_CODEC_ID_MPL2 = 96266 |> UInt32
const AV_CODEC_ID_VPLAYER = 96267 |> UInt32
const AV_CODEC_ID_PJS = 96268 |> UInt32
const AV_CODEC_ID_ASS = 96269 |> UInt32
const AV_CODEC_ID_HDMV_TEXT_SUBTITLE = 96270 |> UInt32
const AV_CODEC_ID_TTML = 96271 |> UInt32
const AV_CODEC_ID_FIRST_UNKNOWN = 98304 |> UInt32
const AV_CODEC_ID_TTF = 98304 |> UInt32
const AV_CODEC_ID_SCTE_35 = 98305 |> UInt32
const AV_CODEC_ID_BINTEXT = 100352 |> UInt32
const AV_CODEC_ID_XBIN = 100353 |> UInt32
const AV_CODEC_ID_IDF = 100354 |> UInt32
const AV_CODEC_ID_OTF = 100355 |> UInt32
const AV_CODEC_ID_SMPTE_KLV = 100356 |> UInt32
const AV_CODEC_ID_DVD_NAV = 100357 |> UInt32
const AV_CODEC_ID_TIMED_ID3 = 100358 |> UInt32
const AV_CODEC_ID_BIN_DATA = 100359 |> UInt32
const AV_CODEC_ID_PROBE = 102400 |> UInt32
const AV_CODEC_ID_MPEG2TS = 131072 |> UInt32
const AV_CODEC_ID_MPEG4SYSTEMS = 131073 |> UInt32
const AV_CODEC_ID_FFMETADATA = 135168 |> UInt32
const AV_CODEC_ID_WRAPPED_AVFRAME = 135169 |> UInt32
# end enum AVCodecID

const AV_CODEC_ID_IFF_BYTERUN1 = AV_CODEC_ID_IFF_ILBM
const AV_CODEC_ID_H265 = AV_CODEC_ID_HEVC
const AV_CODEC_PROP_INTRA_ONLY = 1 << 0
const AV_CODEC_PROP_LOSSY = 1 << 1
const AV_CODEC_PROP_LOSSLESS = 1 << 2
const AV_CODEC_PROP_REORDER = 1 << 3
const AV_CODEC_PROP_BITMAP_SUB = 1 << 16
const AV_CODEC_PROP_TEXT_SUB = 1 << 17
const AV_INPUT_BUFFER_PADDING_SIZE = 64
const AV_INPUT_BUFFER_MIN_SIZE = 16384
const AV_CODEC_FLAG_UNALIGNED = 1 << 0
const AV_CODEC_FLAG_QSCALE = 1 << 1
const AV_CODEC_FLAG_4MV = 1 << 2
const AV_CODEC_FLAG_OUTPUT_CORRUPT = 1 << 3
const AV_CODEC_FLAG_QPEL = 1 << 4
const AV_CODEC_FLAG_PASS1 = 1 << 9
const AV_CODEC_FLAG_PASS2 = 1 << 10
const AV_CODEC_FLAG_LOOP_FILTER = 1 << 11
const AV_CODEC_FLAG_GRAY = 1 << 13
const AV_CODEC_FLAG_PSNR = 1 << 15
const AV_CODEC_FLAG_TRUNCATED = 1 << 16
const AV_CODEC_FLAG_INTERLACED_DCT = 1 << 18
const AV_CODEC_FLAG_LOW_DELAY = 1 << 19
const AV_CODEC_FLAG_GLOBAL_HEADER = 1 << 22
const AV_CODEC_FLAG_BITEXACT = 1 << 23
const AV_CODEC_FLAG_AC_PRED = 1 << 24
const AV_CODEC_FLAG_INTERLACED_ME = 1 << 29
const AV_CODEC_FLAG_CLOSED_GOP = UInt32(1) << 31
const AV_CODEC_FLAG2_FAST = 1 << 0
const AV_CODEC_FLAG2_NO_OUTPUT = 1 << 2
const AV_CODEC_FLAG2_LOCAL_HEADER = 1 << 3
const AV_CODEC_FLAG2_DROP_FRAME_TIMECODE = 1 << 13
const AV_CODEC_FLAG2_CHUNKS = 1 << 15
const AV_CODEC_FLAG2_IGNORE_CROP = 1 << 16
const AV_CODEC_FLAG2_SHOW_ALL = 1 << 22
const AV_CODEC_FLAG2_EXPORT_MVS = 1 << 28
const AV_CODEC_FLAG2_SKIP_MANUAL = 1 << 29
const AV_CODEC_FLAG2_RO_FLUSH_NOOP = 1 << 30
const AV_CODEC_CAP_DRAW_HORIZ_BAND = 1 << 0
const AV_CODEC_CAP_DR1 = 1 << 1
const AV_CODEC_CAP_TRUNCATED = 1 << 3
const AV_CODEC_CAP_DELAY = 1 << 5
const AV_CODEC_CAP_SMALL_LAST_FRAME = 1 << 6
const AV_CODEC_CAP_SUBFRAMES = 1 << 8
const AV_CODEC_CAP_EXPERIMENTAL = 1 << 9
const AV_CODEC_CAP_CHANNEL_CONF = 1 << 10
const AV_CODEC_CAP_FRAME_THREADS = 1 << 12
const AV_CODEC_CAP_SLICE_THREADS = 1 << 13
const AV_CODEC_CAP_PARAM_CHANGE = 1 << 14
const AV_CODEC_CAP_AUTO_THREADS = 1 << 15
const AV_CODEC_CAP_VARIABLE_FRAME_SIZE = 1 << 16
const AV_CODEC_CAP_AVOID_PROBING = 1 << 17
const AV_CODEC_CAP_INTRA_ONLY = 0x40000000
const AV_CODEC_CAP_LOSSLESS = 0x80000000
const AV_CODEC_CAP_HARDWARE = 1 << 18
const AV_CODEC_CAP_HYBRID = 1 << 19
const AV_GET_BUFFER_FLAG_REF = 1 << 0

# begin enum AVPacketSideDataType
const AVPacketSideDataType = UInt32
const AV_PKT_DATA_PALETTE = 0 |> UInt32
const AV_PKT_DATA_NEW_EXTRADATA = 1 |> UInt32
const AV_PKT_DATA_PARAM_CHANGE = 2 |> UInt32
const AV_PKT_DATA_H263_MB_INFO = 3 |> UInt32
const AV_PKT_DATA_REPLAYGAIN = 4 |> UInt32
const AV_PKT_DATA_DISPLAYMATRIX = 5 |> UInt32
const AV_PKT_DATA_STEREO3D = 6 |> UInt32
const AV_PKT_DATA_AUDIO_SERVICE_TYPE = 7 |> UInt32
const AV_PKT_DATA_QUALITY_STATS = 8 |> UInt32
const AV_PKT_DATA_FALLBACK_TRACK = 9 |> UInt32
const AV_PKT_DATA_CPB_PROPERTIES = 10 |> UInt32
const AV_PKT_DATA_SKIP_SAMPLES = 11 |> UInt32
const AV_PKT_DATA_JP_DUALMONO = 12 |> UInt32
const AV_PKT_DATA_STRINGS_METADATA = 13 |> UInt32
const AV_PKT_DATA_SUBTITLE_POSITION = 14 |> UInt32
const AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL = 15 |> UInt32
const AV_PKT_DATA_WEBVTT_IDENTIFIER = 16 |> UInt32
const AV_PKT_DATA_WEBVTT_SETTINGS = 17 |> UInt32
const AV_PKT_DATA_METADATA_UPDATE = 18 |> UInt32
const AV_PKT_DATA_MPEGTS_STREAM_ID = 19 |> UInt32
const AV_PKT_DATA_MASTERING_DISPLAY_METADATA = 20 |> UInt32
const AV_PKT_DATA_SPHERICAL = 21 |> UInt32
const AV_PKT_DATA_CONTENT_LIGHT_LEVEL = 22 |> UInt32
const AV_PKT_DATA_A53_CC = 23 |> UInt32
const AV_PKT_DATA_ENCRYPTION_INIT_INFO = 24 |> UInt32
const AV_PKT_DATA_ENCRYPTION_INFO = 25 |> UInt32
const AV_PKT_DATA_AFD = 26 |> UInt32
const AV_PKT_DATA_NB = 27 |> UInt32
# end enum AVPacketSideDataType

const AV_PKT_DATA_QUALITY_FACTOR = AV_PKT_DATA_QUALITY_STATS
const AV_PKT_FLAG_KEY = 0x0001
const AV_PKT_FLAG_CORRUPT = 0x0002
const AV_PKT_FLAG_DISCARD = 0x0004
const AV_PKT_FLAG_TRUSTED = 0x0008
const AV_PKT_FLAG_DISPOSABLE = 0x0010
const FF_COMPRESSION_DEFAULT = -1
const FF_PRED_LEFT = 0
const FF_PRED_PLANE = 1
const FF_PRED_MEDIAN = 2
const FF_CMP_SAD = 0
const FF_CMP_SSE = 1
const FF_CMP_SATD = 2
const FF_CMP_DCT = 3
const FF_CMP_PSNR = 4
const FF_CMP_BIT = 5
const FF_CMP_RD = 6
const FF_CMP_ZERO = 7
const FF_CMP_VSAD = 8
const FF_CMP_VSSE = 9
const FF_CMP_NSSE = 10
const FF_CMP_W53 = 11
const FF_CMP_W97 = 12
const FF_CMP_DCTMAX = 13
const FF_CMP_DCT264 = 14
const FF_CMP_MEDIAN_SAD = 15
const FF_CMP_CHROMA = 256
const SLICE_FLAG_CODED_ORDER = 0x0001
const SLICE_FLAG_ALLOW_FIELD = 0x0002
const SLICE_FLAG_ALLOW_PLANE = 0x0004
const FF_MB_DECISION_SIMPLE = 0
const FF_MB_DECISION_BITS = 1
const FF_MB_DECISION_RD = 2
const FF_CODER_TYPE_VLC = 0
const FF_CODER_TYPE_AC = 1
const FF_CODER_TYPE_RAW = 2
const FF_CODER_TYPE_RLE = 3
const FF_BUG_AUTODETECT = 1
const FF_BUG_XVID_ILACE = 4
const FF_BUG_UMP4 = 8
const FF_BUG_NO_PADDING = 16
const FF_BUG_AMV = 32
const FF_BUG_QPEL_CHROMA = 64
const FF_BUG_STD_QPEL = 128
const FF_BUG_QPEL_CHROMA2 = 256
const FF_BUG_DIRECT_BLOCKSIZE = 512
const FF_BUG_EDGE = 1024
const FF_BUG_HPEL_CHROMA = 2048
const FF_BUG_DC_CLIP = 4096
const FF_BUG_MS = 8192
const FF_BUG_TRUNCATED = 16384
const FF_BUG_IEDGE = 32768
const FF_COMPLIANCE_VERY_STRICT = 2
const FF_COMPLIANCE_STRICT = 1
const FF_COMPLIANCE_NORMAL = 0
const FF_COMPLIANCE_UNOFFICIAL = -1
const FF_COMPLIANCE_EXPERIMENTAL = -2
const FF_EC_GUESS_MVS = 1
const FF_EC_DEBLOCK = 2
const FF_EC_FAVOR_INTER = 256
const FF_DEBUG_PICT_INFO = 1
const FF_DEBUG_RC = 2
const FF_DEBUG_BITSTREAM = 4
const FF_DEBUG_MB_TYPE = 8
const FF_DEBUG_QP = 16
const FF_DEBUG_DCT_COEFF = 0x00000040
const FF_DEBUG_SKIP = 0x00000080
const FF_DEBUG_STARTCODE = 0x00000100
const FF_DEBUG_ER = 0x00000400
const FF_DEBUG_MMCO = 0x00000800
const FF_DEBUG_BUGS = 0x00001000
const FF_DEBUG_BUFFERS = 0x00008000
const FF_DEBUG_THREADS = 0x00010000
const FF_DEBUG_GREEN_MD = 0x00800000
const FF_DEBUG_NOMC = 0x01000000
const AV_EF_CRCCHECK = 1 << 0
const AV_EF_BITSTREAM = 1 << 1
const AV_EF_BUFFER = 1 << 2
const AV_EF_EXPLODE = 1 << 3
const AV_EF_IGNORE_ERR = 1 << 15
const AV_EF_CAREFUL = 1 << 16
const AV_EF_COMPLIANT = 1 << 17
const AV_EF_AGGRESSIVE = 1 << 18
const FF_DCT_AUTO = 0
const FF_DCT_FASTINT = 1
const FF_DCT_INT = 2
const FF_DCT_MMX = 3
const FF_DCT_ALTIVEC = 5
const FF_DCT_FAAN = 6
const FF_IDCT_AUTO = 0
const FF_IDCT_INT = 1
const FF_IDCT_SIMPLE = 2
const FF_IDCT_SIMPLEMMX = 3
const FF_IDCT_ARM = 7
const FF_IDCT_ALTIVEC = 8
const FF_IDCT_SIMPLEARM = 10
const FF_IDCT_XVID = 14
const FF_IDCT_SIMPLEARMV5TE = 16
const FF_IDCT_SIMPLEARMV6 = 17
const FF_IDCT_FAAN = 20
const FF_IDCT_SIMPLENEON = 22
const FF_IDCT_NONE = 24
const FF_IDCT_SIMPLEAUTO = 128
const FF_THREAD_FRAME = 1
const FF_THREAD_SLICE = 2
const FF_PROFILE_UNKNOWN = -99
const FF_PROFILE_RESERVED = -100
const FF_PROFILE_AAC_MAIN = 0
const FF_PROFILE_AAC_LOW = 1
const FF_PROFILE_AAC_SSR = 2
const FF_PROFILE_AAC_LTP = 3
const FF_PROFILE_AAC_HE = 4
const FF_PROFILE_AAC_HE_V2 = 28
const FF_PROFILE_AAC_LD = 22
const FF_PROFILE_AAC_ELD = 38
const FF_PROFILE_MPEG2_AAC_LOW = 128
const FF_PROFILE_MPEG2_AAC_HE = 131
const FF_PROFILE_DNXHD = 0
const FF_PROFILE_DNXHR_LB = 1
const FF_PROFILE_DNXHR_SQ = 2
const FF_PROFILE_DNXHR_HQ = 3
const FF_PROFILE_DNXHR_HQX = 4
const FF_PROFILE_DNXHR_444 = 5
const FF_PROFILE_DTS = 20
const FF_PROFILE_DTS_ES = 30
const FF_PROFILE_DTS_96_24 = 40
const FF_PROFILE_DTS_HD_HRA = 50
const FF_PROFILE_DTS_HD_MA = 60
const FF_PROFILE_DTS_EXPRESS = 70
const FF_PROFILE_MPEG2_422 = 0
const FF_PROFILE_MPEG2_HIGH = 1
const FF_PROFILE_MPEG2_SS = 2
const FF_PROFILE_MPEG2_SNR_SCALABLE = 3
const FF_PROFILE_MPEG2_MAIN = 4
const FF_PROFILE_MPEG2_SIMPLE = 5
const FF_PROFILE_H264_CONSTRAINED = 1 << 9
const FF_PROFILE_H264_INTRA = 1 << 11
const FF_PROFILE_H264_BASELINE = 66
const FF_PROFILE_H264_CONSTRAINED_BASELINE = 66 | FF_PROFILE_H264_CONSTRAINED
const FF_PROFILE_H264_MAIN = 77
const FF_PROFILE_H264_EXTENDED = 88
const FF_PROFILE_H264_HIGH = 100
const FF_PROFILE_H264_HIGH_10 = 110
const FF_PROFILE_H264_HIGH_10_INTRA = 110 | FF_PROFILE_H264_INTRA
const FF_PROFILE_H264_MULTIVIEW_HIGH = 118
const FF_PROFILE_H264_HIGH_422 = 122
const FF_PROFILE_H264_HIGH_422_INTRA = 122 | FF_PROFILE_H264_INTRA
const FF_PROFILE_H264_STEREO_HIGH = 128
const FF_PROFILE_H264_HIGH_444 = 144
const FF_PROFILE_H264_HIGH_444_PREDICTIVE = 244
const FF_PROFILE_H264_HIGH_444_INTRA = 244 | FF_PROFILE_H264_INTRA
const FF_PROFILE_H264_CAVLC_444 = 44
const FF_PROFILE_VC1_SIMPLE = 0
const FF_PROFILE_VC1_MAIN = 1
const FF_PROFILE_VC1_COMPLEX = 2
const FF_PROFILE_VC1_ADVANCED = 3
const FF_PROFILE_MPEG4_SIMPLE = 0
const FF_PROFILE_MPEG4_SIMPLE_SCALABLE = 1
const FF_PROFILE_MPEG4_CORE = 2
const FF_PROFILE_MPEG4_MAIN = 3
const FF_PROFILE_MPEG4_N_BIT = 4
const FF_PROFILE_MPEG4_SCALABLE_TEXTURE = 5
const FF_PROFILE_MPEG4_SIMPLE_FACE_ANIMATION = 6
const FF_PROFILE_MPEG4_BASIC_ANIMATED_TEXTURE = 7
const FF_PROFILE_MPEG4_HYBRID = 8
const FF_PROFILE_MPEG4_ADVANCED_REAL_TIME = 9
const FF_PROFILE_MPEG4_CORE_SCALABLE = 10
const FF_PROFILE_MPEG4_ADVANCED_CODING = 11
const FF_PROFILE_MPEG4_ADVANCED_CORE = 12
const FF_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE = 13
const FF_PROFILE_MPEG4_SIMPLE_STUDIO = 14
const FF_PROFILE_MPEG4_ADVANCED_SIMPLE = 15
const FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_0 = 1
const FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_1 = 2
const FF_PROFILE_JPEG2000_CSTREAM_NO_RESTRICTION = 32768
const FF_PROFILE_JPEG2000_DCINEMA_2K = 3
const FF_PROFILE_JPEG2000_DCINEMA_4K = 4
const FF_PROFILE_VP9_0 = 0
const FF_PROFILE_VP9_1 = 1
const FF_PROFILE_VP9_2 = 2
const FF_PROFILE_VP9_3 = 3
const FF_PROFILE_HEVC_MAIN = 1
const FF_PROFILE_HEVC_MAIN_10 = 2
const FF_PROFILE_HEVC_MAIN_STILL_PICTURE = 3
const FF_PROFILE_HEVC_REXT = 4
const FF_PROFILE_AV1_MAIN = 0
const FF_PROFILE_AV1_HIGH = 1
const FF_PROFILE_AV1_PROFESSIONAL = 2
const FF_PROFILE_MJPEG_HUFFMAN_BASELINE_DCT = 0xc0
const FF_PROFILE_MJPEG_HUFFMAN_EXTENDED_SEQUENTIAL_DCT = 0xc1
const FF_PROFILE_MJPEG_HUFFMAN_PROGRESSIVE_DCT = 0xc2
const FF_PROFILE_MJPEG_HUFFMAN_LOSSLESS = 0xc3
const FF_PROFILE_MJPEG_JPEG_LS = 0xf7
const FF_PROFILE_SBC_MSBC = 1
const FF_LEVEL_UNKNOWN = -99
const FF_SUB_CHARENC_MODE_DO_NOTHING = -1
const FF_SUB_CHARENC_MODE_AUTOMATIC = 0
const FF_SUB_CHARENC_MODE_PRE_DECODER = 1
const FF_SUB_CHARENC_MODE_IGNORE = 2
const FF_DEBUG_VIS_MV_P_FOR = 0x00000001
const FF_DEBUG_VIS_MV_B_FOR = 0x00000002
const FF_DEBUG_VIS_MV_B_BACK = 0x00000004
const FF_CODEC_PROPERTY_LOSSLESS = 0x00000001
const FF_CODEC_PROPERTY_CLOSED_CAPTIONS = 0x00000002
const FF_SUB_TEXT_FMT_ASS = 0
const FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS = 1
const AV_HWACCEL_CODEC_CAP_EXPERIMENTAL = 0x0200
const AV_HWACCEL_FLAG_IGNORE_LEVEL = 1 << 0
const AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH = 1 << 1
const AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH = 1 << 2
const AV_SUBTITLE_FLAG_FORCED = 0x00000001
const AV_PARSER_PTS_NB = 4
const PARSER_FLAG_COMPLETE_FRAMES = 0x0001
const PARSER_FLAG_ONCE = 0x0002
const PARSER_FLAG_FETCHED_OFFSET = 0x0004
const PARSER_FLAG_USE_CODEC_TS = 0x1000

struct AVProfile
    profile::Cint
    name::Cstring
end

struct AVCodecDescriptor
    id::AVCodecID
    _type::AVMediaType
    name::Cstring
    long_name::Cstring
    props::Cint
    mime_types::Ptr{Cstring}
    profiles::Ptr{AVProfile}
end

# begin enum AVDiscard
const AVDiscard = Cint
const AVDISCARD_NONE = -16 |> Int32
const AVDISCARD_DEFAULT = 0 |> Int32
const AVDISCARD_NONREF = 8 |> Int32
const AVDISCARD_BIDIR = 16 |> Int32
const AVDISCARD_NONINTRA = 24 |> Int32
const AVDISCARD_NONKEY = 32 |> Int32
const AVDISCARD_ALL = 48 |> Int32
# end enum AVDiscard

# begin enum AVAudioServiceType
const AVAudioServiceType = UInt32
const AV_AUDIO_SERVICE_TYPE_MAIN = 0 |> UInt32
const AV_AUDIO_SERVICE_TYPE_EFFECTS = 1 |> UInt32
const AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED = 2 |> UInt32
const AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED = 3 |> UInt32
const AV_AUDIO_SERVICE_TYPE_DIALOGUE = 4 |> UInt32
const AV_AUDIO_SERVICE_TYPE_COMMENTARY = 5 |> UInt32
const AV_AUDIO_SERVICE_TYPE_EMERGENCY = 6 |> UInt32
const AV_AUDIO_SERVICE_TYPE_VOICE_OVER = 7 |> UInt32
const AV_AUDIO_SERVICE_TYPE_KARAOKE = 8 |> UInt32
const AV_AUDIO_SERVICE_TYPE_NB = 9 |> UInt32
# end enum AVAudioServiceType

struct RcOverride
    start_frame::Cint
    end_frame::Cint
    qscale::Cint
    quality_factor::Cfloat
end

struct AVPanScan
    id::Cint
    width::Cint
    height::Cint
    position::NTuple{3, NTuple{2, Int16}}
end

struct AVCPBProperties
    max_bitrate::Cint
    min_bitrate::Cint
    avg_bitrate::Cint
    buffer_size::Cint
    vbv_delay::UInt64
end

struct AVPacketSideData
    data::Ptr{UInt8}
    size::Cint
    _type::AVPacketSideDataType
end

struct AVPacket
    buf::Ptr{AVBufferRef}
    pts::Int64
    dts::Int64
    data::Ptr{UInt8}
    size::Cint
    stream_index::Cint
    flags::Cint
    side_data::Ptr{AVPacketSideData}
    side_data_elems::Cint
    duration::Int64
    pos::Int64
    convergence_duration::Int64
end

# begin enum AVSideDataParamChangeFlags
const AVSideDataParamChangeFlags = UInt32
const AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT = 1 |> UInt32
const AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT = 2 |> UInt32
const AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE = 4 |> UInt32
const AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS = 8 |> UInt32
# end enum AVSideDataParamChangeFlags

struct AVCodecInternal
end

# begin enum AVFieldOrder
const AVFieldOrder = UInt32
const AV_FIELD_UNKNOWN = 0 |> UInt32
const AV_FIELD_PROGRESSIVE = 1 |> UInt32
const AV_FIELD_TT = 2 |> UInt32
const AV_FIELD_BB = 3 |> UInt32
const AV_FIELD_TB = 4 |> UInt32
const AV_FIELD_BT = 5 |> UInt32
# end enum AVFieldOrder

struct AVCodecDefault
end

struct AVCodec
    name::Cstring
    long_name::Cstring
    _type::AVMediaType
    id::AVCodecID
    capabilities::Cint
    supported_framerates::Ptr{AVRational}
    pix_fmts::Ptr{AVPixelFormat}
    supported_samplerates::Ptr{Cint}
    sample_fmts::Ptr{AVSampleFormat}
    channel_layouts::Ptr{UInt64}
    max_lowres::UInt8
    priv_class::Ptr{AVClass}
    profiles::Ptr{AVProfile}
    wrapper_name::Cstring
    priv_data_size::Cint
    next::Ptr{AVCodec}
    init_thread_copy::Ptr{Cvoid}
    update_thread_context::Ptr{Cvoid}
    defaults::Ptr{AVCodecDefault}
    init_static_data::Ptr{Cvoid}
    init::Ptr{Cvoid}
    encode_sub::Ptr{Cvoid}
    encode2::Ptr{Cvoid}
    decode::Ptr{Cvoid}
    close::Ptr{Cvoid}
    send_frame::Ptr{Cvoid}
    receive_packet::Ptr{Cvoid}
    receive_frame::Ptr{Cvoid}
    flush::Ptr{Cvoid}
    caps_internal::Cint
    bsfs::Cstring
    # hw_configs::Ptr{Ptr{AVCodecHWConfigInternal}}
    hw_configs::Ptr{Cvoid}
end

struct AVHWAccel
    name::Cstring
    _type::AVMediaType
    id::AVCodecID
    pix_fmt::AVPixelFormat
    capabilities::Cint
    alloc_frame::Ptr{Cvoid}
    start_frame::Ptr{Cvoid}
    decode_params::Ptr{Cvoid}
    decode_slice::Ptr{Cvoid}
    end_frame::Ptr{Cvoid}
    frame_priv_data_size::Cint
    decode_mb::Ptr{Cvoid}
    init::Ptr{Cvoid}
    uninit::Ptr{Cvoid}
    priv_data_size::Cint
    caps_internal::Cint
    frame_params::Ptr{Cvoid}
end

# struct AVFrame
# end

struct AVCodecContext
    av_class::Ptr{AVClass}
    log_level_offset::Cint
    codec_type::AVMediaType
    codec::Ptr{AVCodec}
    codec_id::AVCodecID
    codec_tag::UInt32
    priv_data::Ptr{Cvoid}
    internal::Ptr{AVCodecInternal}
    opaque::Ptr{Cvoid}
    bit_rate::Int64
    bit_rate_tolerance::Cint
    global_quality::Cint
    compression_level::Cint
    flags::Cint
    flags2::Cint
    extradata::Ptr{UInt8}
    extradata_size::Cint
    time_base::AVRational
    ticks_per_frame::Cint
    delay::Cint
    width::Cint
    height::Cint
    coded_width::Cint
    coded_height::Cint
    gop_size::Cint
    pix_fmt::AVPixelFormat
    draw_horiz_band::Ptr{Cvoid}
    get_format::Ptr{Cvoid}
    max_b_frames::Cint
    b_quant_factor::Cfloat
    b_frame_strategy::Cint
    b_quant_offset::Cfloat
    has_b_frames::Cint
    mpeg_quant::Cint
    i_quant_factor::Cfloat
    i_quant_offset::Cfloat
    lumi_masking::Cfloat
    temporal_cplx_masking::Cfloat
    spatial_cplx_masking::Cfloat
    p_masking::Cfloat
    dark_masking::Cfloat
    slice_count::Cint
    prediction_method::Cint
    slice_offset::Ptr{Cint}
    sample_aspect_ratio::AVRational
    me_cmp::Cint
    me_sub_cmp::Cint
    mb_cmp::Cint
    ildct_cmp::Cint
    dia_size::Cint
    last_predictor_count::Cint
    pre_me::Cint
    me_pre_cmp::Cint
    pre_dia_size::Cint
    me_subpel_quality::Cint
    me_range::Cint
    slice_flags::Cint
    mb_decision::Cint
    intra_matrix::Ptr{UInt16}
    inter_matrix::Ptr{UInt16}
    scenechange_threshold::Cint
    noise_reduction::Cint
    intra_dc_precision::Cint
    skip_top::Cint
    skip_bottom::Cint
    mb_lmin::Cint
    mb_lmax::Cint
    me_penalty_compensation::Cint
    bidir_refine::Cint
    brd_scale::Cint
    keyint_min::Cint
    refs::Cint
    chromaoffset::Cint
    mv0_threshold::Cint
    b_sensitivity::Cint
    color_primaries::AVColorPrimaries
    color_trc::AVColorTransferCharacteristic
    colorspace::AVColorSpace
    color_range::AVColorRange
    chroma_sample_location::AVChromaLocation
    slices::Cint
    field_order::AVFieldOrder
    sample_rate::Cint
    channels::Cint
    sample_fmt::AVSampleFormat
    frame_size::Cint
    frame_number::Cint
    block_align::Cint
    cutoff::Cint
    channel_layout::UInt64
    request_channel_layout::UInt64
    audio_service_type::AVAudioServiceType
    request_sample_fmt::AVSampleFormat
    get_buffer2::Ptr{Cvoid}
    refcounted_frames::Cint
    qcompress::Cfloat
    qblur::Cfloat
    qmin::Cint
    qmax::Cint
    max_qdiff::Cint
    rc_buffer_size::Cint
    rc_override_count::Cint
    rc_override::Ptr{RcOverride}
    rc_max_rate::Int64
    rc_min_rate::Int64
    rc_max_available_vbv_use::Cfloat
    rc_min_vbv_overflow_use::Cfloat
    rc_initial_buffer_occupancy::Cint
    coder_type::Cint
    context_model::Cint
    frame_skip_threshold::Cint
    frame_skip_factor::Cint
    frame_skip_exp::Cint
    frame_skip_cmp::Cint
    trellis::Cint
    min_prediction_order::Cint
    max_prediction_order::Cint
    timecode_frame_start::Int64
    rtp_callback::Ptr{Cvoid}
    rtp_payload_size::Cint
    mv_bits::Cint
    header_bits::Cint
    i_tex_bits::Cint
    p_tex_bits::Cint
    i_count::Cint
    p_count::Cint
    skip_count::Cint
    misc_bits::Cint
    frame_bits::Cint
    stats_out::Cstring
    stats_in::Cstring
    workaround_bugs::Cint
    strict_std_compliance::Cint
    error_concealment::Cint
    debug::Cint
    err_recognition::Cint
    reordered_opaque::Int64
    hwaccel::Ptr{AVHWAccel}
    hwaccel_context::Ptr{Cvoid}
    error::NTuple{8, UInt64}
    dct_algo::Cint
    idct_algo::Cint
    bits_per_coded_sample::Cint
    bits_per_raw_sample::Cint
    lowres::Cint
    coded_frame::Ptr{AVFrame}
    thread_count::Cint
    thread_type::Cint
    active_thread_type::Cint
    thread_safe_callbacks::Cint
    execute::Ptr{Cvoid}
    execute2::Ptr{Cvoid}
    nsse_weight::Cint
    profile::Cint
    level::Cint
    skip_loop_filter::AVDiscard
    skip_idct::AVDiscard
    skip_frame::AVDiscard
    subtitle_header::Ptr{UInt8}
    subtitle_header_size::Cint
    vbv_delay::UInt64
    side_data_only_packets::Cint
    initial_padding::Cint
    framerate::AVRational
    sw_pix_fmt::AVPixelFormat
    pkt_timebase::AVRational
    codec_descriptor::Ptr{AVCodecDescriptor}
    pts_correction_num_faulty_pts::Int64
    pts_correction_num_faulty_dts::Int64
    pts_correction_last_pts::Int64
    pts_correction_last_dts::Int64
    sub_charenc::Cstring
    sub_charenc_mode::Cint
    skip_alpha::Cint
    seek_preroll::Cint
    debug_mv::Cint
    chroma_intra_matrix::Ptr{UInt16}
    dump_separator::Ptr{UInt8}
    codec_whitelist::Cstring
    properties::UInt32
    coded_side_data::Ptr{AVPacketSideData}
    nb_coded_side_data::Cint
    hw_frames_ctx::Ptr{AVBufferRef}
    sub_text_format::Cint
    trailing_padding::Cint
    max_pixels::Int64
    hw_device_ctx::Ptr{AVBufferRef}
    hwaccel_flags::Cint
    apply_cropping::Cint
    extra_hw_frames::Cint
end

# begin enum ANONYMOUS_1
const ANONYMOUS_1 = UInt32
const AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX = 1 |> UInt32
const AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX = 2 |> UInt32
const AV_CODEC_HW_CONFIG_METHOD_INTERNAL = 4 |> UInt32
const AV_CODEC_HW_CONFIG_METHOD_AD_HOC = 8 |> UInt32
# end enum ANONYMOUS_1

struct AVCodecHWConfig
    pix_fmt::AVPixelFormat
    methods::Cint
    device_type::AVHWDeviceType
end

struct AVPicture
    data::NTuple{8, Ptr{UInt8}}
    linesize::NTuple{8, Cint}
end

# begin enum AVSubtitleType
const AVSubtitleType = UInt32
const SUBTITLE_NONE = 0 |> UInt32
const SUBTITLE_BITMAP = 1 |> UInt32
const SUBTITLE_TEXT = 2 |> UInt32
const SUBTITLE_ASS = 3 |> UInt32
# end enum AVSubtitleType

struct AVSubtitleRect
    x::Cint
    y::Cint
    w::Cint
    h::Cint
    nb_colors::Cint
    pict::AVPicture
    data::NTuple{4, Ptr{UInt8}}
    linesize::NTuple{4, Cint}
    _type::AVSubtitleType
    text::Cstring
    ass::Cstring
    flags::Cint
end

struct AVSubtitle
    format::UInt16
    start_display_time::UInt32
    end_display_time::UInt32
    num_rects::UInt32
    rects::Ptr{Ptr{AVSubtitleRect}}
    pts::Int64
end

struct MpegEncContext
end

struct AVCodecParameters
    codec_type::AVMediaType
    codec_id::AVCodecID
    codec_tag::UInt32
    extradata::Ptr{UInt8}
    extradata_size::Cint
    format::Cint
    bit_rate::Int64
    bits_per_coded_sample::Cint
    bits_per_raw_sample::Cint
    profile::Cint
    level::Cint
    width::Cint
    height::Cint
    sample_aspect_ratio::AVRational
    field_order::AVFieldOrder
    color_range::AVColorRange
    color_primaries::AVColorPrimaries
    color_trc::AVColorTransferCharacteristic
    color_space::AVColorSpace
    chroma_location::AVChromaLocation
    video_delay::Cint
    channel_layout::UInt64
    channels::Cint
    sample_rate::Cint
    block_align::Cint
    frame_size::Cint
    initial_padding::Cint
    trailing_padding::Cint
    seek_preroll::Cint
end

# begin enum AVPictureStructure
const AVPictureStructure = UInt32
const AV_PICTURE_STRUCTURE_UNKNOWN = 0 |> UInt32
const AV_PICTURE_STRUCTURE_TOP_FIELD = 1 |> UInt32
const AV_PICTURE_STRUCTURE_BOTTOM_FIELD = 2 |> UInt32
const AV_PICTURE_STRUCTURE_FRAME = 3 |> UInt32
# end enum AVPictureStructure

struct AVCodecParser
    codec_ids::NTuple{5, Cint}
    priv_data_size::Cint
    parser_init::Ptr{Cvoid}
    parser_parse::Ptr{Cvoid}
    parser_close::Ptr{Cvoid}
    split::Ptr{Cvoid}
    next::Ptr{AVCodecParser}
end

struct AVCodecParserContext
    priv_data::Ptr{Cvoid}
    parser::Ptr{AVCodecParser}
    frame_offset::Int64
    cur_offset::Int64
    next_frame_offset::Int64
    pict_type::Cint
    repeat_pict::Cint
    pts::Int64
    dts::Int64
    last_pts::Int64
    last_dts::Int64
    fetch_timestamp::Cint
    cur_frame_start_index::Cint
    cur_frame_offset::NTuple{4, Int64}
    cur_frame_pts::NTuple{4, Int64}
    cur_frame_dts::NTuple{4, Int64}
    flags::Cint
    offset::Int64
    cur_frame_end::NTuple{4, Int64}
    key_frame::Cint
    convergence_duration::Int64
    dts_sync_point::Cint
    dts_ref_dts_delta::Cint
    pts_dts_delta::Cint
    cur_frame_pos::NTuple{4, Int64}
    pos::Int64
    last_pos::Int64
    duration::Cint
    field_order::AVFieldOrder
    picture_structure::AVPictureStructure
    output_picture_number::Cint
    width::Cint
    height::Cint
    coded_width::Cint
    coded_height::Cint
    format::Cint
end

struct AVBitStreamFilter
    name::Cstring
    codec_ids::Ptr{AVCodecID}
    priv_class::Ptr{AVClass}
    priv_data_size::Cint
    init::Ptr{Cvoid}
    filter::Ptr{Cvoid}
    close::Ptr{Cvoid}
    flush::Ptr{Cvoid}
end

struct AVBitStreamFilterContext
    priv_data::Ptr{Cvoid}
    filter::Ptr{AVBitStreamFilter}
    parser::Ptr{AVCodecParserContext}
    next::Ptr{AVBitStreamFilterContext}
    args::Cstring
end

struct AVBSFInternal
end

struct AVBSFContext
    av_class::Ptr{AVClass}
    filter::Ptr{AVBitStreamFilter}
    internal::Ptr{AVBSFInternal}
    priv_data::Ptr{Cvoid}
    par_in::Ptr{AVCodecParameters}
    par_out::Ptr{AVCodecParameters}
    time_base_in::AVRational
    time_base_out::AVRational
end

struct AVBSFList
end

# begin enum AVLockOp
const AVLockOp = UInt32
const AV_LOCK_CREATE = 0 |> UInt32
const AV_LOCK_OBTAIN = 1 |> UInt32
const AV_LOCK_RELEASE = 2 |> UInt32
const AV_LOCK_DESTROY = 3 |> UInt32
# end enum AVLockOp

const LIBAVCODEC_VERSION_MAJOR = 58
const LIBAVCODEC_VERSION_MINOR = 35
const LIBAVCODEC_VERSION_MICRO = 100

# Skipping MacroDefinition: LIBAVCODEC_VERSION_INT AV_VERSION_INT ( LIBAVCODEC_VERSION_MAJOR , LIBAVCODEC_VERSION_MINOR , LIBAVCODEC_VERSION_MICRO )
# Skipping MacroDefinition: LIBAVCODEC_VERSION AV_VERSION ( LIBAVCODEC_VERSION_MAJOR , LIBAVCODEC_VERSION_MINOR , LIBAVCODEC_VERSION_MICRO )

# const LIBAVCODEC_BUILD = LIBAVCODEC_VERSION_INT

# Skipping MacroDefinition: LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY ( LIBAVCODEC_VERSION )
# Skipping MacroDefinition: FF_API_LOWRES ( LIBAVCODEC_VERSION_MAJOR < 59 )
# Skipping MacroDefinition: FF_API_DEBUG_MV ( LIBAVCODEC_VERSION_MAJOR < 58 )
# Skipping MacroDefinition: FF_API_AVCTX_TIMEBASE ( LIBAVCODEC_VERSION_MAJOR < 59 )
# Skipping MacroDefinition: FF_API_CODED_FRAME ( LIBAVCODEC_VERSION_MAJOR < 59 )
# Skipping MacroDefinition: FF_API_SIDEDATA_ONLY_PKT ( LIBAVCODEC_VERSION_MAJOR < 59 )
# Skipping MacroDefinition: FF_API_VDPAU_PROFILE ( LIBAVCODEC_VERSION_MAJOR < 59 )
# Skipping MacroDefinition: FF_API_CONVERGENCE_DURATION ( LIBAVCODEC_VERSION_MAJOR < 59 )
# Skipping MacroDefinition: FF_API_AVPICTURE ( LIBAVCODEC_VERSION_MAJOR < 59 )
# Skipping MacroDefinition: FF_API_AVPACKET_OLD_API ( LIBAVCODEC_VERSION_MAJOR < 59 )
# Skipping MacroDefinition: FF_API_RTP_CALLBACK ( LIBAVCODEC_VERSION_MAJOR < 59 )
# Skipping MacroDefinition: FF_API_VBV_DELAY ( LIBAVCODEC_VERSION_MAJOR < 59 )
# Skipping MacroDefinition: FF_API_CODER_TYPE ( LIBAVCODEC_VERSION_MAJOR < 59 )
# Skipping MacroDefinition: FF_API_STAT_BITS ( LIBAVCODEC_VERSION_MAJOR < 59 )
# Skipping MacroDefinition: FF_API_PRIVATE_OPT ( LIBAVCODEC_VERSION_MAJOR < 59 )
# Skipping MacroDefinition: FF_API_ASS_TIMING ( LIBAVCODEC_VERSION_MAJOR < 59 )
# Skipping MacroDefinition: FF_API_OLD_BSF ( LIBAVCODEC_VERSION_MAJOR < 59 )
# Skipping MacroDefinition: FF_API_COPY_CONTEXT ( LIBAVCODEC_VERSION_MAJOR < 59 )
# Skipping MacroDefinition: FF_API_GET_CONTEXT_DEFAULTS ( LIBAVCODEC_VERSION_MAJOR < 59 )
# Skipping MacroDefinition: FF_API_NVENC_OLD_NAME ( LIBAVCODEC_VERSION_MAJOR < 59 )
# Skipping MacroDefinition: FF_API_STRUCT_VAAPI_CONTEXT ( LIBAVCODEC_VERSION_MAJOR < 59 )
# Skipping MacroDefinition: FF_API_MERGE_SD_API ( LIBAVCODEC_VERSION_MAJOR < 59 )
# Skipping MacroDefinition: FF_API_TAG_STRING ( LIBAVCODEC_VERSION_MAJOR < 59 )
# Skipping MacroDefinition: FF_API_GETCHROMA ( LIBAVCODEC_VERSION_MAJOR < 59 )
# Skipping MacroDefinition: FF_API_CODEC_GET_SET ( LIBAVCODEC_VERSION_MAJOR < 59 )
# Skipping MacroDefinition: FF_API_USER_VISIBLE_AVHWACCEL ( LIBAVCODEC_VERSION_MAJOR < 59 )
# Skipping MacroDefinition: FF_API_LOCKMGR ( LIBAVCODEC_VERSION_MAJOR < 59 )
# Skipping MacroDefinition: FF_API_NEXT ( LIBAVCODEC_VERSION_MAJOR < 59 )

const AV_AAC_ADTS_HEADER_SIZE = 7

struct AVDCT
    av_class::Ptr{AVClass}
    idct::Ptr{Cvoid}
    idct_permutation::NTuple{64, UInt8}
    fdct::Ptr{Cvoid}
    dct_algo::Cint
    idct_algo::Cint
    get_pixels::Ptr{Cvoid}
    bits_per_sample::Cint
end

const FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG = 1
const FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO = 2

struct AVD3D11VAContext
    decoder::Ptr{Cint}
    video_context::Ptr{Cint}
    cfg::Ptr{Cint}
    surface_count::UInt32
    surface::Ptr{Ptr{Cint}}
    workaround::UInt64
    report_id::UInt32
    context_mutex::Cint
end

const MAX_DWT_LEVELS = 5

# begin enum DiracParseCodes
const DiracParseCodes = UInt32
const DIRAC_PCODE_SEQ_HEADER = 0 |> UInt32
const DIRAC_PCODE_END_SEQ = 16 |> UInt32
const DIRAC_PCODE_AUX = 32 |> UInt32
const DIRAC_PCODE_PAD = 48 |> UInt32
const DIRAC_PCODE_PICTURE_CODED = 8 |> UInt32
const DIRAC_PCODE_PICTURE_RAW = 72 |> UInt32
const DIRAC_PCODE_PICTURE_LOW_DEL = 200 |> UInt32
const DIRAC_PCODE_PICTURE_HQ = 232 |> UInt32
const DIRAC_PCODE_INTER_NOREF_CO1 = 10 |> UInt32
const DIRAC_PCODE_INTER_NOREF_CO2 = 9 |> UInt32
const DIRAC_PCODE_INTER_REF_CO1 = 13 |> UInt32
const DIRAC_PCODE_INTER_REF_CO2 = 14 |> UInt32
const DIRAC_PCODE_INTRA_REF_CO = 12 |> UInt32
const DIRAC_PCODE_INTRA_REF_RAW = 76 |> UInt32
const DIRAC_PCODE_INTRA_REF_PICT = 204 |> UInt32
const DIRAC_PCODE_MAGIC = 1111638852 |> UInt32
# end enum DiracParseCodes

struct DiracVersionInfo
    major::Cint
    minor::Cint
end

struct AVDiracSeqHeader
    width::UInt32
    height::UInt32
    chroma_format::UInt8
    interlaced::UInt8
    top_field_first::UInt8
    frame_rate_index::UInt8
    aspect_ratio_index::UInt8
    clean_width::UInt16
    clean_height::UInt16
    clean_left_offset::UInt16
    clean_right_offset::UInt16
    pixel_range_index::UInt8
    color_spec_index::UInt8
    profile::Cint
    level::Cint
    framerate::AVRational
    sample_aspect_ratio::AVRational
    pix_fmt::AVPixelFormat
    color_range::AVColorRange
    color_primaries::AVColorPrimaries
    color_trc::AVColorTransferCharacteristic
    colorspace::AVColorSpace
    version::DiracVersionInfo
    bit_depth::Cint
end

const DV_PROFILE_BYTES = 6 * 80

struct AVDVProfile
    dsf::Cint
    video_stype::Cint
    frame_size::Cint
    difseg_size::Cint
    n_difchan::Cint
    time_base::AVRational
    ltc_divisor::Cint
    height::Cint
    width::Cint
    sar::NTuple{2, AVRational}
    pix_fmt::AVPixelFormat
    bpm::Cint
    block_sizes::Ptr{UInt8}
    audio_stride::Cint
    audio_min_samples::NTuple{3, Cint}
    audio_samples_dist::NTuple{5, Cint}
    audio_shuffle::Ptr{NTuple{9, UInt8}}
end

struct AVMediaCodecContext
    surface::Ptr{Cvoid}
end

struct MediaCodecBuffer
end

const AVMediaCodecBuffer = MediaCodecBuffer

struct AVQSVContext
    session::Cint
    iopattern::Cint
    ext_buffers::Ptr{Ptr{Cint}}
    nb_ext_buffers::Cint
    opaque_alloc::Cint
    nb_opaque_surfaces::Cint
    opaque_surfaces::Ptr{AVBufferRef}
    opaque_alloc_type::Cint
end

# const AVVDPAU_Render2 = Ptr{Cvoid}

# struct AVVDPAUContext
#     decoder::VdpDecoder
#     render::Ptr{VdpDecoderRender}
#     render2::AVVDPAU_Render2
# end

# const Picture = QuickdrawPicture

struct AVVideotoolboxContext
    session::Cint
    output_callback::Cint
    cv_pix_fmt_type::Cint
    cm_fmt_desc::Cint
    cm_codec_type::Cint
end

const VORBIS_FLAG_HEADER = 0x00000001
const VORBIS_FLAG_COMMENT = 0x00000002
const VORBIS_FLAG_SETUP = 0x00000004

struct AVVorbisParseContext
end

const AV_XVMC_ID = 0x1dc711c0


text:
module MosaicViews

using PaddedViews
using OffsetArrays
using MappedArrays: of_eltype
using StackViews

export

    MosaicView,
    mosaicview,
    mosaic

"""
    MosaicView(A::AbstractArray)

Create a two dimensional "view" of the three or four dimensional
array `A`. The resulting `MosaicView` will display the data in
`A` such that it emulates using `vcat` for all elements in the
third dimension of `A`, and `hcat` for all elements in the fourth
dimension of `A`.

For example, if `size(A)` is `(2,3,4)`, then the resulting
`MosaicView` will have the size `(2*4,3)` which is `(8,3)`.
Alternatively, if `size(A)` is `(2,3,4,5)`, then the resulting
size will be `(2*4,3*5)` which is `(8,15)`.

Another way to think about this is that `MosaicView` creates a
mosaic of all the individual matrices enumerated in the third
(and optionally fourth) dimension of the given 3D or 4D array
`A`. This can be especially useful for creating a single
composite image from a set of equally sized images.

```@jldoctest
julia> using MosaicViews

julia> A = [(k+1)*l-1 for i in 1:2, j in 1:3, k in 1:2, l in 1:2]
2×3×2×2 Array{Int64,4}:
[:, :, 1, 1] =
 1  1  1
 1  1  1

[:, :, 2, 1] =
 2  2  2
 2  2  2

[:, :, 1, 2] =
 3  3  3
 3  3  3

[:, :, 2, 2] =
 5  5  5
 5  5  5

julia> MosaicView(A)
4×6 MosaicViews.MosaicView{Int64,4,Array{Int64,4}}:
 1  1  1  3  3  3
 1  1  1  3  3  3
 2  2  2  5  5  5
 2  2  2  5  5  5
```
"""
struct MosaicView{T,N,A<:AbstractArray{T,N}} <: AbstractArray{T,2}
    parent::A
    dims::Tuple{Int,Int}
    pdims::NTuple{N,Int}

    function MosaicView{T,N}(A::AbstractArray{T,N}, dims) where {T,N}
        1 <= N <= 4 || throw(ArgumentError("The given array must have dimensionality N=3 or N=4"))
        # unless we store the axes in the struct, we can't support offset indices
        # N=2 is a special case that we can provide a specialization on `axes`
        # but for consistency with cases of other dimensions, disable it as well
        require_one_based_indexing(A)
        new{T,N,typeof(A)}(A, dims, size(A))
    end
end

function MosaicView(A::AbstractArray{T,N}) where {T,N}
    # vectors are lifted to 2D matrix, 3d/4d arrays are reshaped to 2D matrix
    dims = (size(A,1) * size(A,3), size(A,2) * size(A,4))
    MosaicView{T,N}(A, dims)
end

Base.parent(mva::MosaicView) = mva.parent
Base.size(mva::MosaicView) = mva.dims

# fallback for 1d/2d case
@inline Base.getindex(mva::MosaicView, ind::Int...) = mva.parent[ind...]

@inline function Base.getindex(mva::MosaicView{T,3,A}, i::Int, j::Int) where {T,A}
    @boundscheck checkbounds(mva, i, j)
    pdims = mva.pdims
    parent = mva.parent
    idx1 = (i-1) % pdims[1] + 1
    idx2 = (j-1) % pdims[2] + 1
    idx3 = (i-1) ÷ pdims[1] + 1
    @inbounds res = parent[idx1, idx2, idx3]
    res
end

# FIXME: we need the annotation T because mosaicview + StackView is currently not type stable
@inline function Base.getindex(mva::MosaicView{T,4,A}, i::Int, j::Int)::T where {T,A}
    @boundscheck checkbounds(mva, i, j)
    pdims = mva.pdims
    parent = mva.parent
    idx1 = (i-1) % pdims[1] + 1
    idx2 = (j-1) % pdims[2] + 1
    idx3 = (i-1) ÷ pdims[1] + 1
    idx4 = (j-1) ÷ pdims[2] + 1
    @inbounds res = parent[idx1, idx2, idx3, idx4]
    res
end

"""
    mosaicview(A::AbstractArray;
               [fillvalue=<zero unit>], [npad=0],
               [nrow], [ncol], [rowmajor=false]) -> MosaicView
    mosaicview(As::AbstractArray...; kwargs...)
    mosaicview(As::Union{Tuple, AbstractVector}; kwargs...)

Create a two dimensional "view" from array `A`.

The resulting [`MosaicView`](@ref) will display all the matrix
slices of the first two dimensions of `A` arranged as a single
large mosaic (in the form of a matrix).

# Arguments

In contrast to using the constructor of [`MosaicView`](@ref)
directly, the function `mosaicview` also allows for a couple of
convenience keywords. A typical use case would be to create an
image mosaic from a set of input images.

- The parameter `fillvalue` defines the value that
  that should be used for empty space. This can be padding caused
  by `npad`, or empty mosaic tiles in case the number of matrix
  slices in `A` is smaller than `nrow*ncol`.

- The parameter `npad` defines the empty padding space between
  adjacent mosaic tiles. This can be especially useful if the
  individual tiles (i.e. matrix slices in `A`) are images that
  should be visually separated by some grid lines.

- The parameters `nrow` and `ncol` can be used to choose the
  number of tiles in row and/or column direction the mosaic should
  be arranged in. Note that it suffices to specify one of the
  two parameters, as the other one can be inferred accordingly.
  The default in case none of the two are specified is `nrow = size(A,3)`.

- If `rowmajor` is set to `true`, then the slices will be
  arranged left-to-right-top-to-bottom, instead of
  top-to-bottom-left-to-right (default). The layout only differs
  in non-trivial cases, i.e., when `nrow != 1` and `ncol != 1`.

!!! tip
    This function is not type stable and should only be used if
    performance is not a priority. To achieve optimized performance,
    you need to manually construct a [`MosaicView`](@ref).

# Examples

The simplest usage is to `cat` two arrays of the same dimension.

```julia-repl
julia> A1 = fill(1, 3, 1)
3×1 Array{Int64,2}:
 1
 1
 1

julia> A2 = fill(2, 1, 3)
1×3 Array{Int64,2}:
 2  2  2

julia> mosaicview(A1, A2)
6×3 MosaicView{Int64,4, ...}:
 0  1  0
 0  1  0
 0  1  0
 0  0  0
 2  2  2
 0  0  0

julia> mosaicview(A1, A2; center=false)
 6×3 MosaicView{Int64,4, ...}:
  1  0  0
  1  0  0
  1  0  0
  2  2  2
  0  0  0
  0  0  0
```

Other keyword arguments can be useful to get a nice looking results.

```julia-repl
julia> using MosaicViews

julia> A = [k for i in 1:2, j in 1:3, k in 1:5]
2×3×5 Array{Int64,3}:
[:, :, 1] =
 1  1  1
 1  1  1

[:, :, 2] =
 2  2  2
 2  2  2

[:, :, 3] =
 3  3  3
 3  3  3

[:, :, 4] =
 4  4  4
 4  4  4

[:, :, 5] =
 5  5  5
 5  5  5

julia> mosaicview(A, ncol=2)
6×6 MosaicViews.MosaicView{Int64,4,...}:
 1  1  1  4  4  4
 1  1  1  4  4  4
 2  2  2  5  5  5
 2  2  2  5  5  5
 3  3  3  0  0  0
 3  3  3  0  0  0

julia> mosaicview(A, nrow=2)
4×9 MosaicViews.MosaicView{Int64,4,...}:
 1  1  1  3  3  3  5  5  5
 1  1  1  3  3  3  5  5  5
 2  2  2  4  4  4  0  0  0
 2  2  2  4  4  4  0  0  0

julia> mosaicview(A, nrow=2, rowmajor=true)
4×9 MosaicViews.MosaicView{Int64,4,...}:
 1  1  1  2  2  2  3  3  3
 1  1  1  2  2  2  3  3  3
 4  4  4  5  5  5  0  0  0
 4  4  4  5  5  5  0  0  0

julia> mosaicview(A, nrow=2, npad=1, rowmajor=true)
5×11 MosaicViews.MosaicView{Int64,4,...}:
 1  1  1  0  2  2  2  0  3  3  3
 1  1  1  0  2  2  2  0  3  3  3
 0  0  0  0  0  0  0  0  0  0  0
 4  4  4  0  5  5  5  0  0  0  0
 4  4  4  0  5  5  5  0  0  0  0

julia> mosaicview(A, fillvalue=-1, nrow=2, npad=1, rowmajor=true)
5×11 MosaicViews.MosaicView{Int64,4,...}:
  1   1   1  -1   2   2   2  -1   3   3   3
  1   1   1  -1   2   2   2  -1   3   3   3
 -1  -1  -1  -1  -1  -1  -1  -1  -1  -1  -1
  4   4   4  -1   5   5   5  -1  -1  -1  -1
  4   4   4  -1   5   5   5  -1  -1  -1  -1
```
"""
function mosaicview(A::AbstractArray{T,3};
                    fillvalue = zero(T),
                    npad = 0,
                    nrow = -1,
                    ncol = -1,
                    rowmajor = false,
                    kwargs...) where T   # delete `kwargs...` when we delete the `center` depwarn
    nrow == -1 || nrow > 0 || throw(ArgumentError("The parameter \"nrow\" must be greater than 0"))
    ncol == -1 || ncol > 0 || throw(ArgumentError("The parameter \"ncol\" must be greater than 0"))
    npad >= 0 || throw(ArgumentError("The parameter \"npad\" must be greater than or equal to 0"))
    if !isempty(kwargs)
        if haskey(kwargs, :center)
            Base.depwarn("use of `center` in `mosaicview` is deprecated; see `mosaic`", :mosaicview)
        else
            Base.depwarn("passing extraneous keyword arguments $(kwargs.data) to `mosaicview` is deprecated", :mosaicview)
        end
    end
    ntile = size(A,3)
    ntile_ceil = ntile # ntile need not be integer divideable
    if nrow == -1 && ncol == -1
        # automatically choose nrow to reflect what MosaicView does
        nrow = ntile
        ncol = 1
    elseif nrow == -1
        # compute nrow based on ncol
        nrow = ceil(Int, ntile / ncol)
        ntile_ceil = nrow * ncol
    elseif ncol == -1
        # compute ncol based on nrow
        ncol = ceil(Int, ntile / nrow)
        ntile_ceil = nrow * ncol
    else
        # accept nrow and ncol as is if it covers at least all
        # existing tiles
        ntile_ceil = nrow * ncol
        ntile_ceil < ntile && throw(ArgumentError("The product of the parameters \"ncol\" (value: $ncol) and \"nrow\" (value: $nrow) must be greater than or equal to $ntile"))
    end
    # we pad size(A,3) to nrow*ncol. we also pad the first two
    # dimensions according to npad. think of this as border
    # between tiles (useful for images)
    pad_dims = (size(A,1) + npad, size(A,2) + npad, ntile_ceil)
    A_pad = PaddedView(convert(T, fillvalue), A, pad_dims)
    # next we reshape the image such that it reflects the
    # specified nrow and ncol
    A_new = if !rowmajor
        res_dims = (size(A_pad,1), size(A_pad,2), nrow, ncol)
        reshape(A_pad, res_dims)
    else
        # same as above but we additionally permute dimensions
        # to mimic row first layout for the tiles. this is useful
        # for images since user often reads these from left-to-right
        # before top-to-bottom. (note the swap of "ncol" and "nrow")
        res_dims = (size(A_pad,1), size(A_pad,2), ncol, nrow)
        A_tp = reshape(A_pad, res_dims)
        PermutedDimsArray{eltype(A_tp), 4, (1, 2, 4, 3), (1, 2, 4, 3), typeof(A_tp)}(A_tp)
    end
    # decrease size of the resulting MosaicView by npad to not have
    # a border on the right side and bottom side of the final mosaic.
    dims = (size(A_new,1) * size(A_new,3) - npad, size(A_new,2) * size(A_new,4) - npad)
    MosaicView{T,4}(A_new, dims)
end

function mosaicview(A::AbstractArray{T,N};
                    nrow = -1,
                    ncol = -1,
                    kwargs...) where {T,N}
    # if neither nrow nor ncol is provided then automatically choose
    # nrow and ncol to reflect what MosaicView does (i.e. use size)
    if nrow == -1 && ncol == -1
        nrow = size(A, 3)
        # ncol = size(A, 4)
    end
    mosaicview(reshape(A, (size(A,1), size(A,2), :));
               nrow=nrow, ncol=ncol, kwargs...)
end

"""
    mosaic(A1, A2...; center=true, kwargs...)
    mosaic([A1, A2, ...]; center=true, kwargs...)

Create a mosaic out of input arrays `A1`, `A2`, .... `mosaic` is essentially
a more flexible version of `cat` or `hvcat`; like them it makes a copy of
the inputs rather than returning a "view."

If `center` is set to `true`, then the padded arrays will be shifted
to the center; if set to false, they shift to the top-left corner. This
parameter is only useful when arrays are of different sizes.

All the keyword arguments of [`mosaicview`](@ref) are also supported.
"""
@inline mosaic(As::AbstractArray...; kwargs...) = mosaic(As; kwargs...)

function mosaic(As::AbstractVector{<:AbstractArray};
                fillvalue=zero(_filltype(As)),
                center::Bool=true,
                kwargs...)
    length(As) == 0 && throw(ArgumentError("The given vector should not be empty"))
    nd = ndims(As[1])
    all(A->ndims(A)==nd, As) || throw(ArgumentError("All arrays should have the same dimension"))
    T = _filltype(As)
    fillvalue = convert(T, fillvalue)
    mosaicview(_padded_cat(As; center=center, fillvalue=fillvalue, dims=valdim(first(As)));
               fillvalue=fillvalue, kwargs...)
end

function mosaic(As::Tuple;
                fillvalue=zero(_filltype(As)),
                center::Bool=true,
                kwargs...)
    length(As) == 0 && throw(ArgumentError("The given tuple should not be empty"))
    nd = ndims(As[1])
    all(A->ndims(A)==nd, As) || throw(ArgumentError("All arrays should have the same dimension"))
    T = _filltype(As)
    fillvalue = convert(T, fillvalue)
    vd = valdim(first(As))
    if isconcretetype(eltype(As)) || VERSION < v"1.2.0"
        # Base.inferencebarrier requires Julia at least v1.2.0
        mosaicview(_padded_cat(As; center=center, fillvalue=fillvalue, dims=vd);
                fillvalue=fillvalue, kwargs...)
    else
        # Reduce latency by despecializing calls with heterogeneous array types
        mosaicview(_padded_cat(Base.inferencebarrier(As); center=center, fillvalue=Base.inferencebarrier(fillvalue), dims=Base.inferencebarrier(vd));
                fillvalue=fillvalue, kwargs...)
    end
end

valdim(A::AbstractArray{T,0}) where T     = Val(3)
valdim(A::AbstractVector)                 = Val(3)
valdim(A::AbstractMatrix)                 = Val(3)
valdim(A::AbstractArray{T,N}) where {T,N} = Val(N+1)

function _padded_cat(imgs, center::Bool, fillvalue, dims)
    @nospecialize # because this is frequently called with heterogeneous inputs, we @nospecialize it
    pv(@nospecialize(imgs::AbstractVector{<:AbstractArray})) = PaddedViews.paddedviews_itr(fillvalue, imgs)
    pv(@nospecialize(imgs)) = paddedviews(fillvalue, imgs...)
    sym_pv(@nospecialize(imgs::AbstractVector{<:AbstractArray})) = PaddedViews.sym_paddedviews_itr(fillvalue, imgs)
    sym_pv(@nospecialize(imgs)) = sym_paddedviews(fillvalue, imgs...)

    pv_fn = center ? sym_pv : pv
    return StackView{_filltype(imgs)}(pv_fn(imgs), dims)
end
# compat: some packages uses this method
_padded_cat(imgs; center::Bool, fillvalue, dims) = _padded_cat(imgs, center, fillvalue, dims)

has_common_axes(@nospecialize(imgs)) = isempty(imgs) || all(isequal(axes(first(imgs))) ∘ axes, imgs)

# This uses Union{} as a sentinel eltype (all other types "beat" it),
# and Bool as a near-neutral fill type.
_filltype(As) = PaddedViews.filltype(Bool, _filltypeT(Union{}, As...))

@inline _filltypeT(::Type{T}, A, tail...) where T = _filltypeT(promote_wrapped_type(T, _gettype(A)), tail...)
_filltypeT(::Type{T}) where T = T

# When the inputs are homogenous we can circumvent varargs despecialization
# This also handles the case of empty `As` but concrete `T`.
function _filltype(As::AbstractVector{A}) where A<:AbstractArray{T} where T
    # (!@isdefined(T) || T === Any) && return invoke(_filltype, Tuple{Any}, As)
    T === Any && return invoke(_filltype, Tuple{Any}, As)
    return PaddedViews.filltype(Bool, T)
end

_gettype(A::AbstractArray{T}) where T = T === Any ? typeof(first(A)) : T

"""
    promote_wrapped_type(S, T)

Similar to `promote_type`, except designed to be extensible to cases where you want to promote should occur through a wrapper type.

`promote_wrapped_type` is used by `_filltype` to compute the common element type for handling heterogeneous types when building the mosaic.
It does not have the order-independence of `promote_type`, and you should extend it directly rather than via a `promote_rule`-like mechanism.

# Example

Suppose you have
```
struct MyWrapper{T}
    x::T
end
```
and you don't want to define `promote_type(MyWrapper{Int},Float32)` generally as anything other than `Any`,
but for the purpose of building mosaics a `MyWrapper{Float32}` would be a valid common type.
Then you could define

```
MosaicViews.promote_wrapped_type(::Type{MyWrapper{S}}, ::Type{MyWrapper{T}}) where {S,T} = MyWrapper{MosaicViews.promote_wrapped_type(S,T)}
MosaicViews.promote_wrapped_type(::Type{MyWrapper{S}}, ::Type{T}) where {S,T} = MyWrapper{MosaicViews.promote_wrapped_type(S,T)}
MosaicViews.promote_wrapped_type(::Type{S}, ::Type{MyWrapper{T}}) where {S,T} = MosaicViews.promote_wrapped_type(MyWrapper{T}, S)
```
"""
promote_wrapped_type(::Type{S}, ::Type{T}) where {S, T} = promote_type(S, T)

### compat
if VERSION < v"1.2"
    require_one_based_indexing(A...) = !Base.has_offset_axes(A...) || throw(ArgumentError("offset arrays are not supported but got an array with index other than 1"))
else
    const require_one_based_indexing = Base.require_one_based_indexing
end

### deprecations

@deprecate mosaicview(A1::AbstractArray, A2::AbstractArray; kwargs...) mosaic(A1, A2; kwargs...) # prevent A2 from being interpreted as fillvalue
@deprecate mosaicview(As::AbstractArray...; kwargs...) mosaic(As...; kwargs...)
@deprecate mosaicview(As::AbstractVector{<:AbstractArray};
                      fillvalue=zero(_filltype(As)),
                      center::Bool=true,
                      kwargs...) mosaic(As; fillvalue=fillvalue, center=center, kwargs...)
@deprecate mosaicview(As::Tuple;
                      fillvalue=zero(_filltype(As)),
                      center::Bool=true,
                      kwargs...) mosaic(As; fillvalue=fillvalue, center=center, kwargs...)

end # module

ext: jl


text:
using Documenter, Mimi

makedocs(
    modules = [Mimi],
	sitename = "Mimi.jl",
	pages = [
		"Home" => "index.md",
		"Installation Guide" => "installation.md",
		"User Guide" => "userguide.md",
		"Tutorials" => Any[
			"Tutorials Intro" => "tutorials/tutorial_main.md",
			"1 Run an Existing Model" => "tutorials/tutorial_1.md",
			"2 Modify an Existing Model" => "tutorials/tutorial_2.md",
			"3 Create a Model" => "tutorials/tutorial_3.md",
			"4 Sensitivity Analysis" => "tutorials/tutorial_4.md"
		],
		"FAQ" => "faq.md",
		"Reference" => "reference.md",
		"Integration Guide: Port to v0.5.0" => "integrationguide.md"],

		format = Documenter.HTML(prettyurls = get(ENV, "JULIA_NO_LOCAL_PRETTY_URLS", nothing) === nothing)
)

deploydocs(
    repo = "github.com/mimiframework/Mimi.jl.git",
)


text:
"""Convert a dict with string keys to a NamedTuple, for python-eqsue kwargs splatting"""
function symbolize(d::Dict{String,Any})::NamedTuple
    return (; (Symbol(k) => v for (k, v) in d)...)
end

function new_model(optimizer_factory)::JuMP.Model
    return JuMP.Model(optimizer_factory)
end

"""
    interval_loop(factory_like, model_kwargs, solver_kwargs, interval, n_interval,
                  start_index, inputfolder, outputfolder)

Given:
- optimizer instantiation object `factory_like`:
    something that can be passed to new_model (goes to JuMP.Model by default)
- a dictionary of model keyword arguments `model_kwargs`
- a dictionary of solver keyword arguments `solver_kwargs`
- an interval length `interval` (hours)
- a number of intervals `n_interval`
- a starting index position `start_index`
- a folder path to load all input files from `inputfolder`
- a folder path to write output files to `outputfolder`

Build a model, and run through the intervals, re-building the model and/or
re-setting constraint right-hand-side values as necessary.
"""
function interval_loop(
    factory_like,
    model_kwargs::Dict,
    solver_kwargs::Dict,
    interval::Int,
    n_interval::Int,
    start_index::Int,
    inputfolder::String,
    outputfolder::String,
)
    # Bad (but known) statuses to match against
    numeric_statuses = (
        JuMP.MOI.INFEASIBLE_OR_UNBOUNDED, JuMP.MOI.NUMERICAL_ERROR, JuMP.MOI.OTHER_LIMIT
    )
    infeasible_statuses = (JuMP.MOI.INFEASIBLE, JuMP.MOI.INFEASIBLE_OR_UNBOUNDED)
    # Constant parameters
    case = model_kwargs["case"]
    storage = model_kwargs["storage"]
    demand_flexibility = model_kwargs["demand_flexibility"]
    sets = _make_sets(case; storage=storage, demand_flexibility=demand_flexibility)
    unused_load_shed_intervals_turnoff = 14
    # Start looping
    for i in 1:n_interval
        # These must be declared global so that they persist through the loop.
        global m, pg0, storage_e0, init_shifted_demand, intervals_without_loadshed
        @show ("load_shed_enabled" in keys(model_kwargs))
        @show ("BarHomogeneous" in keys(solver_kwargs))
        interval_start = start_index + (i - 1) * interval
        interval_end = interval_start + interval - 1
        model_kwargs["start_index"] = interval_start
        if demand_flexibility.enabled
            (bus_demand_flex_amt_up, bus_demand_flex_amt_dn) = _make_bus_demand_flexibility_amount(
                case, demand_flexibility, interval_start, interval_end
            )
        end
        if i == 1
            # Build a model with no initial ramp constraint
            if storage.enabled
                model_kwargs["storage_e0"] = storage.sd_table.InitialStorage
            end
            if demand_flexibility.enabled
                model_kwargs["init_shifted_demand"] = zeros(size(bus_demand_flex_amt_dn, 1))
            end
            m = new_model(factory_like)
            JuMP.set_optimizer_attributes(m, pairs(solver_kwargs)...)
            m = _build_model(m; symbolize(model_kwargs)...)
        elseif i == 2
            # Build a model with an initial ramp constraint
            model_kwargs["initial_ramp_enabled"] = true
            model_kwargs["initial_ramp_g0"] = pg0
            if storage.enabled
                model_kwargs["storage_e0"] = storage_e0
            end
            if demand_flexibility.enabled
                model_kwargs["init_shifted_demand"] = init_shifted_demand
            end
            m = new_model(factory_like)
            JuMP.set_optimizer_attributes(m, pairs(solver_kwargs)...)
            m = _build_model(m; symbolize(model_kwargs)...)
        else
            # Reassign right-hand-side of constraints to match profiles
            bus_demand = _make_bus_demand(case, interval_start, interval_end)
            simulation_hydro = permutedims(
                Matrix(case.hydro[interval_start:interval_end, 2:end])
            )
            simulation_solar = permutedims(
                Matrix(case.solar[interval_start:interval_end, 2:end])
            )
            simulation_wind = permutedims(
                Matrix(case.wind[interval_start:interval_end, 2:end])
            )
            for t in 1:interval, b in sets.load_bus_idx
                JuMP.set_normalized_rhs(m[:powerbalance][b, t], bus_demand[b, t])
            end
            if (
                ("load_shed_enabled" in keys(model_kwargs)) &&
                (model_kwargs["load_shed_enabled"] == true)
            )
                for t in 1:interval, i in 1:length(sets.load_bus_idx)
                    JuMP.set_normalized_rhs(
                        m[:load_shed_ub][i, t], bus_demand[sets.load_bus_idx[i], t]
                    )
                end
            end
            for t in 1:interval, g in 1:(sets.num_hydro)
                JuMP.set_normalized_rhs(m[:hydro_fixed][g, t], simulation_hydro[g, t])
            end
            for t in 1:interval, g in 1:(sets.num_solar)
                JuMP.set_normalized_rhs(m[:solar_max][g, t], simulation_solar[g, t])
            end
            for t in 1:interval, g in 1:(sets.num_wind)
                JuMP.set_normalized_rhs(m[:wind_max][g, t], simulation_wind[g, t])
            end
            # Re-assign right-hand-side for initial conditions
            noninf_ramp_idx = findall(case.gen_ramp30 .!= Inf)
            for g in noninf_ramp_idx
                rhs = case.gen_ramp30[g] * 2 + pg0[g]
                JuMP.set_normalized_rhs(m[:initial_rampup][g], rhs)
                rhs = case.gen_ramp30[g] * 2 - pg0[g]
                JuMP.set_normalized_rhs(m[:initial_rampdown][g], rhs)
            end
            if storage.enabled
                for s in 1:(sets.num_storage)
                    JuMP.set_normalized_rhs(m[:initial_soc][s], storage_e0[s])
                end
            end
            if demand_flexibility.enabled
                if !isnothing(demand_flexibility.cost_up)
                    bus_demand_flex_cost_up = permutedims(
                        Matrix(
                            demand_flexibility.cost_up[interval_start:interval_end, 2:end]
                        ),
                    )
                end
                if !isnothing(demand_flexibility.cost_dn)
                    bus_demand_flex_cost_dn = permutedims(
                        Matrix(
                            demand_flexibility.cost_dn[interval_start:interval_end, 2:end]
                        ),
                    )
                end
                for l in 1:(sets.num_flexible_bus)
                    for t in 1:interval
                        JuMP.set_upper_bound(
                            m[:load_shift_up][l, t], bus_demand_flex_amt_up[l, t]
                        )
                        JuMP.set_upper_bound(
                            m[:load_shift_dn][l, t], bus_demand_flex_amt_dn[l, t]
                        )
                        if !isnothing(demand_flexibility.cost_up)
                            JuMP.set_objective_coefficient(
                                m, m[:load_shift_up][l, t], bus_demand_flex_cost_up[l, t]
                            )
                        end
                        if !isnothing(demand_flexibility.cost_dn)
                            JuMP.set_objective_coefficient(
                                m, m[:load_shift_dn][l, t], bus_demand_flex_cost_dn[l, t]
                            )
                        end
                    end
                    if demand_flexibility.rolling_balance
                        JuMP.set_normalized_rhs(
                            m[:rolling_load_balance_first][l], -1 * init_shifted_demand[l]
                        )
                    end
                    if demand_flexibility.interval_balance
                        JuMP.set_normalized_rhs(
                            m[:interval_load_balance][l], -1 * init_shifted_demand[l]
                        )
                    end
                end
            end
        end

        while true
            global results
            # Solve the model, flushing before/after for proper stdout order
            flush(stdout)
            JuMP.optimize!(m)
            flush(stdout)
            status = JuMP.termination_status(m)
            if status == JuMP.MOI.OPTIMAL
                f = JuMP.objective_value(m)
                results = get_results(f, model_kwargs["case"], demand_flexibility)
                break
            elseif (
                (status == JuMP.MOI.LOCALLY_SOLVED) &
                ("load_shed_enabled" in keys(model_kwargs))
            )
                # if load shedding is enabled, we'll accept 'suboptimal'
                f = JuMP.objective_value(m)
                results = get_results(f, model_kwargs["case"], demand_flexibility)
                break
            elseif (
                (status in numeric_statuses) &
                (JuMP.solver_name(m) == "Gurobi") &
                !("BarHomogeneous" in keys(solver_kwargs))
            )
                # if Gurobi, and BarHomogeneous is not enabled, enable it and re-solve
                solver_kwargs["BarHomogeneous"] = 1
                println("enable BarHomogeneous")
                JuMP.set_optimizer_attribute(m, "BarHomogeneous", 1)
            elseif (
                (status in infeasible_statuses) &
                !("load_shed_enabled" in keys(model_kwargs))
            )
                # if load shed not enabled, enable it and re-build the model
                model_kwargs["load_shed_enabled"] = true
                println("rebuild with load shed")
                m = new_model(factory_like)
                JuMP.set_optimizer_attributes(m, pairs(solver_kwargs)...)
                m = _build_model(m; symbolize(model_kwargs)...)
                intervals_without_loadshed = 0
            elseif (
                (JuMP.solver_name(m) == "Gurobi") &
                !("BarHomogeneous" in keys(solver_kwargs))
            )
                # if Gurobi, and BarHomogeneous is not enabled, enable it and re-solve
                solver_kwargs["BarHomogeneous"] = 1
                println("enable BarHomogeneous")
                JuMP.set_optimizer_attribute(m, "BarHomogeneous", 1)
            elseif !("load_shed_enabled" in keys(model_kwargs))
                model_kwargs["load_shed_enabled"] = true
                println("rebuild with load shed")
                m = new_model(factory_like)
                JuMP.set_optimizer_attributes(m, pairs(solver_kwargs)...)
                m = _build_model(m; symbolize(model_kwargs)...)
                intervals_without_loadshed = 0
            else
                # Something has gone very wrong
                @show status
                @show keys(model_kwargs)
                @show keys(solver_kwargs)
                @show JuMP.objective_value(m)
                if (
                    ("load_shed_enabled" in keys(model_kwargs)) &&
                    (model_kwargs["load_shed_enabled"] == true)
                )
                    # Display where load shedding is occurring
                    load_shed_values = JuMP.value.(m[:load_shed])
                    load_shed_indices = findall(load_shed_values .> 1e-6)
                    if length(load_shed_indices) > 0
                        @show load_shed_indices
                        @show load_shed_values[load_shed_indices]
                        @show sum(load_shed_values[load_shed_indices])
                    end
                end
                error("Unknown status code!")
            end
        end

        # Save initial conditions for next interval
        pg0 = results.pg[:, end]
        if storage.enabled
            storage_e0 = results.storage_e[:, end]
        end
        if demand_flexibility.enabled
            if demand_flexibility.interval_balance || demand_flexibility.rolling_balance
                init_shifted_demand = dropdims(
                    sum(results.load_shift_up - results.load_shift_dn; dims=2); dims=2
                )
            else
                init_shifted_demand = zeros(size(bus_demand_flex_amt_dn, 1))
            end
        end

        # Save results
        results_filename = "result_" * string(i - 1) * ".mat"
        results_filepath = joinpath(outputfolder, results_filename)
        save_results(results, results_filepath)

        # If load shedding is enabled but hasn't been used for a while, disable
        if (
            ("load_shed_enabled" in keys(model_kwargs)) &&
            (model_kwargs["load_shed_enabled"] == true)
        )
            total_load_shed = sum(results.load_shed)
            if total_load_shed < 1e-3
                intervals_without_loadshed += 1
            else
                intervals_without_loadshed = 0
            end
            if intervals_without_loadshed == unused_load_shed_intervals_turnoff
                println("rebuilding without load_shed")
                # delete! will work here even if the key is not present
                delete!(solver_kwargs, "BarHomogeneous")
                delete!(model_kwargs, "load_shed_enabled")
                m = new_model(factory_like)
                JuMP.set_optimizer_attributes(m, pairs(solver_kwargs)...)
                m = _build_model(m; symbolize(model_kwargs)...)
            end
        end
    end

    return m
end