unit AnyQV;

interface
uses
  Windows;


// Bitstream Version
const
  XVID_BS_VERSION = 34;

//****************************************************************************
// error codes
//****************************************************************************

// all functions return values <0 indicate error
const
  XVID_ERR_FAIL = -1;       // general fault
  XVID_ERR_MEMORY = -2;     // memory allocation error
  XVID_ERR_FORMAT = -3;     // file format error
  XVID_ERR_VERSION = -4;    // structure version not supported
  XVID_ERR_END = -5;        // encoder only; end of stream reached



//****************************************************************************
// xvid_image_t
//****************************************************************************

// colorspace values
const
 XVID_CSP_PLANAR = (1 shl 0);       // 4:2:0 planar (==I420, except for pointers/strides)
  XVID_CSP_USER = XVID_CSP_PLANAR;
  XVID_CSP_I420 = (1 shl 1);        // 4:2:0 planar
  XVID_CSP_YV12 = (1 shl 2);        // 4:2:0 planar
  XVID_CSP_YUY2 = (1 shl 3);        // 4:2:2 packed
  XVID_CSP_UYVY = (1 shl 4);        // 4:2:2 packed
  XVID_CSP_YVYU = (1 shl 5);        // 4:2:2 packed
  XVID_CSP_BGRA = (1 shl 6);        // 32-bit bgra packed
  XVID_CSP_ABGR = (1 shl 7);        // 32-bit abgr packed
  XVID_CSP_RGBA = (1 shl 8);        // 32-bit rgba packed
  XVID_CSP_ARGB = (1 shl 15);       // 32-bit argb packed
  XVID_CSP_BGR = (1 shl 9);         // 24-bit bgr packed
  XVID_CSP_RGB555 = (1 shl 10);     // 16-bit rgb555 packed
  XVID_CSP_RGB565 = (1 shl 11);     // 16-bit rgb565 packed
  XVID_CSP_SLICE = (1 shl 12);      // decoder only: 4:2:0 planar, per slice rendering
  XVID_CSP_INTERNAL = (1 shl 13);   // decoder only: 4:2:0 planar, returns ptrs to internal buffers
  XVID_CSP_NULL = (1 shl 14);       // decoder only: dont output anything
  XVID_CSP_VFLIP = (1 shl 31);      // vertical flip mask

// xvid_image_t
type
  xvid_image_t = packed record
    csp: Integer;                          // [in] colorspace; or with XVID_CSP_VFLIP to perform vertical flip
    plane: Array[0..4-1] of Pointer;       // [in] image plane ptrs
    stride: Array[0..4-1] of Integer;      // [in] image stride; "bytes per row"
  end;

// video-object-sequence profiles
const
  XVID_PROFILE_S_L0 = $08;    // simple
  XVID_PROFILE_S_L1 = $01;
  XVID_PROFILE_S_L2 = $02;
  XVID_PROFILE_S_L3 = $03;
  XVID_PROFILE_ARTS_L1 = $91; // advanced realtime simple
  XVID_PROFILE_ARTS_L2 = $92;
  XVID_PROFILE_ARTS_L3 = $93;
  XVID_PROFILE_ARTS_L4 = $94;
  XVID_PROFILE_AS_L0 = $f0;   // advanced simple
  XVID_PROFILE_AS_L1 = $f1;
  XVID_PROFILE_AS_L2 = $f2;
  XVID_PROFILE_AS_L3 = $f3;
  XVID_PROFILE_AS_L4 = $f4;

// aspect ratios
const
  XVID_PAR_11_VGA = 1;        // 1:1 vga (square), default if supplied PAR is not a valid value
  XVID_PAR_43_PAL = 2;        // 4:3 pal (12:11 625-line)
  XVID_PAR_43_NTSC = 3;       // 4:3 ntsc (10:11 525-line)
  XVID_PAR_169_PAL = 4;       // 16:9 pal (16:11 625-line)
  XVID_PAR_169_NTSC = 5;      // 16:9 ntsc (40:33 525-line)
  XVID_PAR_EXT = 15;          // extended par; use par_width, par_height

// frame type flags
const
  XVID_TYPE_VOL = -1;       // decoder only: vol was decoded
  XVID_TYPE_NOTHING = 0;    // decoder only (encoder stats): nothing was decoded/encoded
  XVID_TYPE_AUTO = 0;       // encoder: automatically determine coding type
  XVID_TYPE_IVOP = 1;       // intra frame
  XVID_TYPE_PVOP = 2;       // predicted frame
  XVID_TYPE_BVOP = 3;       // bidirectionally encoded
  XVID_TYPE_SVOP = 4;       // predicted+sprite frame


//****************************************************************************
// xvid_global()
//****************************************************************************

// cpu_flags definitions (make sure to sync this with cpuid.asm for ia32)
const
  XVID_CPU_FORCE = (1 shl 31);    // force passed cpu flags
  XVID_CPU_ASM = (1 shl 7);       // native assembly
  // ARCH_IS_IA32
  XVID_CPU_MMX = (1 shl 0);       // mmx : pentiumMMX,k6
  XVID_CPU_MMXEXT = (1 shl 1);    // mmx-ext : pentium2, athlon
  XVID_CPU_SSE = (1 shl 2);       // sse : pentium3, athlonXP
  XVID_CPU_SSE2 = (1 shl 3);      // sse2 : pentium4, athlon64
  XVID_CPU_3DNOW = (1 shl 4);     // 3dnow : k6-2
  XVID_CPU_3DNOWEXT = (1 shl 5);  // 3dnow-ext : athlon
  XVID_CPU_TSC = (1 shl 6);       // tsc : Pentium
  // ARCH_IS_PPC
  XVID_CPU_ALTIVEC = (1 shl 0);   // altivec

  XVID_DEBUG_ERROR = (1 shl 0);
  XVID_DEBUG_STARTCODE = (1 shl 1);
  XVID_DEBUG_HEADER = (1 shl 2);
  XVID_DEBUG_TIMECODE = (1 shl 3);
  XVID_DEBUG_MB = (1 shl 4);
  XVID_DEBUG_COEFF = (1 shl 5);
  XVID_DEBUG_MV = (1 shl 6);
  XVID_DEBUG_RC = (1 shl 7);
  XVID_DEBUG_DEBUG = (1 shl 31);

// XVID_GBL_INIT param1
type
  xvid_gbl_init_t = packed record
    version: Integer;
    cpu_flags: Word;     // [in:opt] zero = autodetect cpu; XVID_CPU_FORCE or {cpu features} = force cpu features
    debug: Integer;      // [in:opt] debug level
  end;

// XVID_GBL_INFO param1
  xvid_gbl_info_t = packed record
    version: Integer;
    actual_version: Integer;  // [out] returns the actual xvidcore version
    build: Pchar;             // [out] if !null, points to description of this xvid core build
    cpu_flags: Word;          // [out] detected cpu features
    num_threads: Integer;     // [out] detected number of cpus/threads
  end;

// XVID_GBL_CONVERT param1
  xvid_gbl_convert_t = packed record
    version: Integer;
    input: XVID_IMAGE_T;      // [in] input image  and  colorspace
    output: XVID_IMAGE_T;     // [in] output image  and  colorspace
    width: Integer;           // [in] width
    height: Integer;          // [in] height
    interlacing: Integer;     // [in] interlacing
  end;

const
  XVID_GBL_INIT = 0;          // initialize xvidcore; must be called before using xvid_decore, or xvid_encore)
  XVID_GBL_INFO = 1;          // return some info about xvidcore, and the host computer
  XVID_GBL_CONVERT = 2;       // colorspace conversion utility

type
  xvid_global = function(handle: Pointer;
                        opt: Integer;
                        param1: Pointer;
                        param2: Pointer): Integer; cdecl;


//****************************************************************************
// xvid_decore()
//****************************************************************************
const
  XVID_DEC_CREATE = 0;  // create decore instance; return 0 on success
  XVID_DEC_DESTROY = 1; // destroy decore instance: return 0 on success
  XVID_DEC_DECODE = 2;  // decode a frame: returns number of bytes consumed >= 0

type
  xvid_decore = function(handle: Pointer;
                        opt: Integer;
                        param1: Pointer;
                        param2: Pointer): Integer; cdecl;

// XVID_DEC_CREATE param 1
//-image width  and  height may be specified here when the dimensions are
//known in advance.

type
  xvid_dec_create_t = packed record
    version: Integer;
    width: Integer;       // [in:opt] image width
    height: Integer;      // [in:opt] image width
    handle: Pointer;      // [out] decore context handle
  end;

// XVID_DEC_DECODE param1
// general flags
const
  XVID_LOWDELAY = (1 shl 0);      // lowdelay mode
  XVID_DISCONTINUITY = (1 shl 1); // indicates break in stream
  XVID_DEBLOCKY = (1 shl 2);      // perform luma deblocking
  XVID_DEBLOCKUV = (1 shl 3);     // perform chroma deblocking
  XVID_FILMEFFECT = (1 shl 4);    // adds film grain

type
  xvid_dec_frame_t = packed record
    version: Integer;
    general: Integer;       // [in:opt] general flags
    bitstream: Pointer;     // [in] bitstream (read from)
    length: Integer;        // [in] bitstream length
    output: XVID_IMAGE_T;   // [in] output image (written to)
  end;


// XVID_DEC_DECODE param2 :: optional
  vop = packed record
    version: Integer;
    _type: Integer;           // [out] output data type
                              // type>0 {XVID_TYPE_IVOP,XVID_TYPE_PVOP,XVID_TYPE_BVOP,XVID_TYPE_SVOP}
    general: Integer;         // [out] flags
    time_base: Integer;       // [out] time base
    time_increment: Integer;  // [out] time increment

// XXX: external deblocking stuff
    qscale: PInteger;         // [out] pointer to quantizer table
    qscale_stride: Integer;   // [out] quantizer scale stride
  end;

  vol = record     // XVID_TYPE_VOL
    general: Integer;         // [out] flags
    width: Integer;           // [out] width
    height: Integer;          // [out] height
    par: Integer;             // [out] pixel aspect ratio (refer to XVID_PAR_xxx above)
    par_width: Integer;       // [out] aspect ratio width [1..255]
    par_height: Integer;      // [out] aspect ratio height [1..255]
  end;

const
  XVID_ZONE_QUANT = (1 shl 0);
  XVID_ZONE_WEIGHT = (1 shl 1);

type
  Pxvid_enc_zone_t = ^xvid_enc_zone_t;
  xvid_enc_zone_t = packed record
    frame: Integer;
    mode: Integer;
    increment: Integer;
    base: Integer;
  end;


//----------------------------------------------------------------------------
// xvid_enc_stats_t structure
//
// Used in:
// - xvid_plg_data_t structure
// - optional parameter in xvid_encore() function
//
// .coding_type = XVID_TYPE_NOTHING if the stats are not given
//----------------------------------------------------------------------------

type
  xvid_enc_stats_t = packed record
    version: Integer;          // encoding parameters
    _type: Integer;            // [out] coding type
    quant: Integer;            // [out] frame quantizer
    vol_flags: Integer;        // [out] vol flags (see above)
    vop_flags: Integer;        // [out] vop flags (see above)

   // bitrate
    length: Integer;           // [out] frame length
    hlength: Integer;          // [out] header length (bytes)
    kblks: Integer;            // [out] number of blocks compressed as Intra
    mblks: Integer;            // [out] number of blocks compressed as Inter
    ublks: Integer;            // [out] number of blocks marked as not_coded

    sse_y: Integer;            // [out] Y plane's sse
    sse_u: Integer;            // [out] U plane's sse
    sse_v: Integer;            // [out] V plane's sse
  end;

//****************************************************************************
{-xvid plugin system -- internals }

{-xvidcore will call XVID_PLG_INFO and XVID_PLG_CREATE during XVID_ENC_CREATE }
{-before encoding each frame xvidcore will call XVID_PLG_BEFORE }
{-after encoding each frame xvidcore will call XVID_PLG_AFTER }
{-xvidcore will call XVID_PLG_DESTROY during XVID_ENC_DESTROY }
//****************************************************************************

const
  XVID_PLG_CREATE = (1 shl 0);
  XVID_PLG_DESTROY = (1 shl 1);
  XVID_PLG_INFO = (1 shl 2);
  XVID_PLG_BEFORE = (1 shl 3);
  XVID_PLG_FRAME = (1 shl 4);
  XVID_PLG_AFTER = (1 shl 5);

// xvid_plg_info_t.flags*/ }
  XVID_REQORIGINAL = (1 shl 0); // plugin requires a copy of the original (uncompressed) image
  XVID_REQPSNR = (1 shl 1);     // plugin requires psnr between the uncompressed and compressed image
  XVID_REQDQUANTS = (1 shl 2);  // plugin requires access to the dquant table


type
  xvid_plg_info_t = packed record
    version: Integer;
    flags: Integer;             // [in:opt] plugin flags
  end;

  xvid_plg_create_t = packed record
    version: Integer;
    num_zones: Integer;         // [out]
    zones: PXVID_ENC_ZONE_T;    // [out]

    width: Integer;             // [out]
    height: Integer;            // [out]
    mb_width: Integer;          // [out]
    mb_height: Integer;         // [out]
    fincr: Integer;             // [out]
    fbase: Integer;             // [out]

    param: Pointer;             // [out]
  end;

  xvid_plg_destroy_t = packed record
    version: Integer;
    num_frames: Integer;        // [out] total frame encoded
  end;

  xvid_plg_data_t = packed record
    version: Integer;
    zone: PXVID_ENC_ZONE_T;     // [out] current zone

    width: Integer;             // [out]
    height: Integer;            // [out]
    mb_width: Integer;          // [out]
    mb_height: Integer;         // [out]
    fincr: Integer;             // [out]
    fbase: Integer;             // [out]

    min_quant: Array[0..3-1] of Integer;     // [out]
    max_quant: Array[0..3-1] of Integer;     // [out]

    reference: XVID_IMAGE_T;    // [out] -> [out]
    current: XVID_IMAGE_T;      // [out] -> [in,out]
    original: XVID_IMAGE_T;     // [out] after: points the original (uncompressed) copy of the current frame
    frame_num: Integer;         // [out] frame number

    _type: Integer;             // [in,out]
    quant: Integer;             // [in,out]

    dquant: PInteger;           // [in,out] pointer to diff quantizer table
    dquant_stride: Integer;     // [in,out] diff quantizer stride

    vop_flags: Integer;         // [in,out]
    vol_flags: Integer;         // [in,out]
    motion_flags: Integer;      // [in,out]

// Deprecated, use the stats field instead. }
// Will disapear before 1.0 }
    length: Integer;            // [out] after: length of encoded frame
    kblks: Integer;             // [out] number of blocks compressed as Intra
    mblks: Integer;             // [out] number of blocks compressed as Inter
    ublks: Integer;             // [out] number of blocks marked not_coded
    sse_y: Integer;             // [out] Y plane's sse
    sse_u: Integer;             // [out] U plane's sse
    sse_v: Integer;             // [out] V plane's sse
// End of duplicated data, kept only for binary compatibility*/ }

    bquant_ratio: Integer;      // [in]
    bquant_offset: Integer;     // [in]

    stats: XVID_ENC_STATS_T;    // [out] frame statistics
  end;

//****************************************************************************
{-xvid plugin system -- external }

{-the application passes xvid an array of "xvid_plugin_t" at XVID_ENC_CREATE. the array }
{-indicates the plugin function pointer and plugin-specific data. }
{-xvidcore handles the rest. example: }

{-xvid_enc_create_t create; }
{-xvid_enc_plugin_t plugins[2]; }

{-plugins[0].func = xvid_psnr_func; }
{-plugins[0].param = NULL; }
{-plugins[1].func = xvid_cbr_func; }
{-plugins[1].param =  and cbr_data; }

{-create.num_plugins = 2; }
{-create.plugins = plugins; }

//****************************************************************************

type
  XVID_PLUGIN_FUNC = function(HANDLE: pointer; OPT: Integer; PARAM1, PARAM2: Pointer):Integer;

  Pxvid_enc_plugin_t = ^xvid_enc_plugin_t;
  xvid_enc_plugin_t = packed record
    func: XVID_PLUGIN_FUNC;
    param: Pointer;
  end;

{ single-pass rate control }
{ two-pass rate control: first pass }
{ two-pass rate control: second pass }

{ lumimasking }

{ write psnr values to stdout }
{ dump before and after yuvpgms }


{ single pass rate control }
{ CBR and Constant quantizer modes }
type
  xvid_plugin_single_t = packed record
    version: Integer;
    bitrate: Integer;                 // [in] bits per second
    reaction_delay_factor: Integer;   // [in]
    averaging_period: Integer;        // [in]
    buffer: Integer;                  // [in]
  end;

  xvid_plugin_2pass1_t = packed record
    version: Integer;
    filename: PChar;
  end;


const
  XVID_PAYBACK_BIAS = 0; // payback with bias
  XVID_PAYBACK_PROP = 1; // payback proportionally

type
  xvid_plugin_2pass2_t = packed record
    version: Integer;
    bitrate: Integer;                    // [in] bits per second
    filename: PChar;                     // [in] first pass stats filename

    keyframe_boost: Integer;             // [in] keyframe boost percentage: [0..100]
    curve_compression_high: Integer;     // [in] percentage of compression performed on the high part of the curve (above average) }
    curve_compression_low: Integer;      // [in] percentage of compression performed on the low part of the curve (below average) }
    overflow_control_strength: Integer;  // [in] Payback delay expressed in number of frames }
    max_overflow_improvement: Integer;   // [in] percentage of allowed range for a frame that gets bigger because of overflow bonus }
    max_overflow_degradation: Integer;   // [in] percentage of allowed range for a frame that gets smaller because of overflow penalty }

    kfreduction: Integer;                // [in] maximum bitrate reduction applied to an iframe under the kfthreshold distance limit }
    kfthreshold: Integer;                // [in] if an iframe is closer to the next iframe than this distance, a quantity of bits }
                                         // is substracted from its bit allocation. The reduction is computed as multiples of
                                         // kfreduction/kthreshold. It reaches kfreduction when the distance == kfthreshold,
                                         // 0 for 1<distance<kfthreshold }

    container_frame_overhead: Integer;   // [in] How many bytes the controller has to compensate per frame due to container format overhead }
  end;

//****************************************************************************
// ENCODER API
//****************************************************************************

//----------------------------------------------------------------------------
// Encoder operations
//----------------------------------------------------------------------------
const
  XVID_ENC_CREATE = 0;    // create encoder instance; returns 0 on success
  XVID_ENC_DESTROY = 1;   // destroy encoder instance; returns 0 on success
  XVID_ENC_ENCODE = 2;    //* encode a frame: returns number of ouput bytes
                          // * 0 means this frame should not be written (ie. encoder lag)
//----------------------------------------------------------------------------
// Encoder entry point
//----------------------------------------------------------------------------
type
  xvid_encore = function(handle: Pointer;
                        opt: Integer;
                        param1: Pointer;
                        param2: Pointer): Integer; cdecl;

// Quick API reference
//
// XVID_ENC_CREATE operation
// - handle: ignored
// - opt: XVID_ENC_CREATE
// - param1: address of a xvid_enc_create_t structure
// - param2: ignored
//
// XVID_ENC_ENCODE operation
// - handle: an instance returned by a CREATE op
// - opt: XVID_ENC_ENCODE
// - param1: address of a xvid_enc_frame_t structure
// - param2: address of a xvid_enc_stats_t structure (optional)
// its return value is asynchronous to what is written to the buffer
// depending on the delay introduced by bvop use. It's display
// ordered.
//
// XVID_ENC_DESTROY operation
// - handle: an instance returned by a CREATE op
// - opt: XVID_ENC_DESTROY
// - param1: ignored
// - param2: ignored


//----------------------------------------------------------------------------
// "Global" flags
//
// These flags are used for xvid_enc_create_t->global field during instance
// creation (operation XVID_ENC_CREATE)
//----------------------------------------------------------------------------

const
  XVID_GLOBAL_PACKED = (1 shl 0);             // packed bitstream
  XVID_GLOBAL_CLOSED_GOP = (1 shl 1);         // closed_gop: was DX50BVOP dx50 bvop compatibility
  XVID_GLOBAL_EXTRASTATS_ENABLE = (1 shl 2);
{$IFDEF 0}
  XVID_GLOBAL_VOL_AT_IVOP = (1 shl 3);        // write vol at every ivop: WIN32/divx compatibility
  XVID_GLOBAL_FORCE_VOL = (1 shl 4);          // when vol-based parameters are changed, insert an ivop NOT recommended
{$ENDIF}

//----------------------------------------------------------------------------
// "VOL" flags
//
// These flags are used for xvid_enc_frame_t->vol_flags field during frame
// encoding (operation XVID_ENC_ENCODE)
//----------------------------------------------------------------------------

const
  XVID_VOL_MPEGQUANT = (1 shl 0);       // enable MPEG type quantization
  XVID_VOL_EXTRASTATS = (1 shl 1);      // enable plane sse stats
  XVID_VOL_QUARTERPEL = (1 shl 2);      // enable quarterpel: frames will encoded as quarterpel
  XVID_VOL_GMC = (1 shl 3);             // enable GMC; frames will be checked for gmc suitability
  XVID_VOL_REDUCED_ENABLE = (1 shl 4);  // enable reduced resolution vops: frames will be checked for rrv suitability
  XVID_VOL_INTERLACING = (1 shl 5);     // enable interlaced encoding

//----------------------------------------------------------------------------
// "VOP" flags
//
// These flags are used for xvid_enc_frame_t->vop_flags field during frame
// encoding (operation XVID_ENC_ENCODE)
//----------------------------------------------------------------------------

// Always valid
const
  XVID_VOP_DEBUG = (1 shl 0);                 // print debug messages in frames
  XVID_VOP_HALFPEL = (1 shl 1);               // use halfpel interpolation
  XVID_VOP_INTER4V = (1 shl 2);               // use 4 motion vectors per MB
  XVID_VOP_TRELLISQUANT = (1 shl 3);          // use trellis based R-D 'optimal' quantization
  XVID_VOP_CHROMAOPT = (1 shl 4);             // enable chroma optimization pre-filter
  XVID_VOP_CARTOON = (1 shl 5);               // use 'cartoon mode'
  XVID_VOP_GREYSCALE = (1 shl 6);             // enable greyscale only mode (even for color input material chroma is ignored)
  XVID_VOP_HQACPRED = (1 shl 7);              // high quality ac prediction
  XVID_VOP_MODEDECISION_RD = (1 shl 8);       // enable DCT-ME and use it for mode decision
  XVID_VOP_FAST_MODEDECISION_RD = (1 shl 12); // use simplified R-D mode decision

// Only valid for vol_flags or =XVID_VOL_INTERLACING
const
  XVID_VOP_TOPFIELDFIRST = (1 shl 9);     // set top-field-first flag
  XVID_VOP_ALTERNATESCAN = (1 shl 10);    // set alternate vertical scan flag

// only valid for vol_flags or =XVID_VOL_REDUCED_ENABLED
  XVID_VOP_REDUCED = (1 shl 11);          // reduced resolution vop

//----------------------------------------------------------------------------
// "Motion" flags
//
// These flags are used for xvid_enc_frame_t->motion field during frame
// encoding (operation XVID_ENC_ENCODE)
//----------------------------------------------------------------------------

// Motion Estimation Search Patterns
const
  XVID_ME_ADVANCEDDIAMOND16 = (1 shl 0);  // use advdiamonds instead of diamonds as search pattern
  XVID_ME_ADVANCEDDIAMOND8 = (1 shl 1);   // use advdiamond for XVID_ME_EXTSEARCH8
  XVID_ME_USESQUARES16 = (1 shl 2);       // use squares instead of diamonds as search pattern
  XVID_ME_USESQUARES8 = (1 shl 3);        // use square for XVID_ME_EXTSEARCH8

// SAD operator based flags
  XVID_ME_HALFPELREFINE16 = (1 shl 4);
  XVID_ME_HALFPELREFINE8 = (1 shl 6);
  XVID_ME_QUARTERPELREFINE16 = (1 shl 7);
  XVID_ME_QUARTERPELREFINE8 = (1 shl 8);
  XVID_ME_GME_REFINE = (1 shl 9);
  XVID_ME_EXTSEARCH16 = (1 shl 10);       // extend PMV by more searches
  XVID_ME_EXTSEARCH8 = (1 shl 11);        // use diamond/square for extended 8x8 search
  XVID_ME_CHROMA_PVOP = (1 shl 12);       // also use chroma for P_VOP/S_VOP ME
  XVID_ME_CHROMA_BVOP = (1 shl 13);       // also use chroma for B_VOP ME
  XVID_ME_FASTREFINE16 = (1 shl 25);      // use low-complexity refinement functions
  XVID_ME_FASTREFINE8 = (1 shl 29);       // low-complexity 8x8 sub-block refinement

// Rate Distortion based flags
// Valid when XVID_VOP_MODEDECISION_RD is enabled
  XVID_ME_HALFPELREFINE16_RD = (1 shl 14);    // perform RD-based halfpel refinement
  XVID_ME_HALFPELREFINE8_RD = (1 shl 15);     // perform RD-based halfpel refinement for 8x8 mode
  XVID_ME_QUARTERPELREFINE16_RD = (1 shl 16); // perform RD-based qpel refinement
  XVID_ME_QUARTERPELREFINE8_RD = (1 shl 17);  // perform RD-based qpel refinement for 8x8 mode
  XVID_ME_EXTSEARCH_RD = (1 shl 18);          // perform RD-based search using square pattern enable XVID_ME_EXTSEARCH8 to do this in 8x8 search as well
  XVID_ME_CHECKPREDICTION_RD = (1 shl 19);    // always check vector equal to prediction

// Other
  XVID_ME_DETECT_STATIC_MOTION = (1 shl 24);  // speed-up ME by detecting stationary scenes
  XVID_ME_SKIP_DELTASEARCH = (1 shl 26);      // speed-up by skipping b-frame delta search
  XVID_ME_FAST_MODEINTERPOLATE = (1 shl 27);  // speed-up by partly skipping interpolate mode
  XVID_ME_BFRAME_EARLYSTOP = (1 shl 28);      // speed-up by early exiting b-search

// Unused
  XVID_ME_UNRESTRICTED16 = (1 shl 20);  // unrestricted ME, not implemented
  XVID_ME_OVERLAPPING16 = (1 shl 21);   // overlapping ME, not implemented
  XVID_ME_UNRESTRICTED8 = (1 shl 22);   // unrestricted ME, not implemented
  XVID_ME_OVERLAPPING8 = (1 shl 23);    // overlapping ME, not implemented


//----------------------------------------------------------------------------
// xvid_enc_create_t structure definition
//
// This structure is passed as param1 during an instance creation (operation
// XVID_ENC_CREATE)
//----------------------------------------------------------------------------

type
  xvid_enc_create_t = packed record
    version: Integer;
    profile: Integer;                 // [in] profile@level; refer to XVID_PROFILE_xxx
    width: Integer;                   // [in] frame dimensions; width, pixel units
    height: Integer;                  // [in] frame dimensions; height, pixel units

    num_zones: Integer;               // [in:opt] number of bitrate zones
    zones: PXVID_ENC_ZONE_T;          // ^^ zone array

    num_plugins: Integer;             // [in:opt] number of plugins
    plugins: PXVID_ENC_PLUGIN_T;      // ^^ plugin array

    num_threads: Integer;             // [in:opt] number of threads
    max_bframes: Integer;             // [in:opt] max sequential bframes (0=disable bframes)

    global: Integer;                  // [in:opt] global flags; controls encoding behavior
                                      // --- vol-based stuff; included here for convenience
    fincr: Integer;                   // [in:opt] framerate increment; set to zero for variable framerate
    fbase: Integer;                   // [in] framerate base frame_duration = fincr/fbase seconds
    // ----------------------------------------------
    // --- vop-based; included here for convenience
    max_key_interval: Integer;        // [in:opt] the maximum interval between key frames

    frame_drop_ratio: Integer;        // [in:opt] frame dropping: 0=drop none... 100=drop all

    bquant_ratio: Integer;            // [in:opt] bframe quantizer multipier/offeset; used to decide bframes quant when bquant==-1
    bquant_offset: Integer;           // bquant = (avg(past_ref_quant,future_ref_quant)*bquant_ratio + bquant_offset) / 100

    min_quant: Array[0..3-1] of Integer;    // [in:opt]
    max_quant: Array[0..3-1] of Integer;    // [in:opt]
    // ----------------------------------------------

    handle: Pointer;                  // [out] encoder instance handle
  end;

//----------------------------------------------------------------------------
// xvid_enc_frame_t structure definition
//
// This structure is passed as param1 during a frame encoding (operation
// XVID_ENC_ENCODE)
//----------------------------------------------------------------------------

// out value for the frame structure->type field
// unlike stats output in param2, this field is not asynchronous and tells
// the client app, if the frame written into the stream buffer is an ivop
// usually used for indexing purpose in the container
const
  XVID_KEYFRAME = (1 shl 1);

// The structure
type
  xvid_enc_frame_t = packed record
    version: Integer;
        // VOL related stuff
        // unless XVID_FORCEVOL is set, the encoder will not react to any changes
        // here until the next VOL (keyframe).

    vol_flags: Integer;             // [in] vol flags
    quant_intra_matrix: PByte;      // [in:opt] custom intra qmatrix
    quant_inter_matrix: PByte;      // [in:opt] custom inter qmatrix

    par: Integer;                   // [in:opt] pixel aspect ratio (refer to XVID_PAR_xxx above)
    par_width: Integer;             // [in:opt] aspect ratio width
    par_height: Integer;            // [in:opt] aspect ratio height

    // Other fields that can change on a frame base
    fincr: Integer;                 // [in:opt] framerate increment, for variable framerate only
    vop_flags: Integer;             // [in] (general)vop-based flags
    motion: Integer;                // [in] ME options

    input: XVID_IMAGE_T;            // [in] input image (read from)

    _type: Integer;                 // [in:opt] coding type
    quant: Integer;                 // [in] frame quantizer; if <=0, automatic (ratecontrol)
    bframe_threshold: Integer;
    bitstream: Pointer;             // [in:opt] bitstream ptr (written to)
    length: Integer;                // [in:opt] bitstream length (bytes)

    out_flags: Integer;             // [out] bitstream output flags
  end;

//****************************************************************************
// versioning
//****************************************************************************

function  XVID_MAKE_VERSION(a,b,c: Integer): Integer;
function  XVID_VERSION_MAJOR(a: Integer): Byte;
function  XVID_VERSION_MINOR(a: Integer): Byte;
function  XVID_VERSION_PATCH(a: Integer): Byte;

function  XVID_MAKE_API(a,b: Integer): Integer;
function  XVID_API_MAJOR(a: Integer): Integer;
function  XVID_API_MINOR(a: Integer): Integer;

var
  XVID_VERSION : integer;
  XVID_API : Integer;

  CodeInited: Boolean;
  ENCodehandle: Pointer;
  DECodehandle: Pointer;
  outbuf : array [0..352*288*3-1] of byte;                          // *
  TmpBuf : array [0..352*288*3-1] of byte;                          // *
  DecBuf : array [0..352*288*3-1] of byte;                          // -
  TmpDecBuf : array [0..352*288*3-1] of byte;                       // -
//  rcvbuf : array [0..352*288*3-1] of byte;                          //
//  TestBuf : array [0..352*288*3-1] of byte;                         //
  CurFRAMESize: Integer;
  Vencodeproc: xvid_encore;
  VDecodeproc: xvid_decore;

function InitCode(width:Integer= 160; height:Integer=120; rate:Integer=15): boolean;
function InitEnCode(width:Integer= 160; height:Integer=120; rate:Integer=15): boolean;
//function InitDeCode(width:Integer= 160; height:Integer=120; rate:Integer=15): boolean;

procedure UninitCode;

implementation

uses SysUtils, math, forms;
const
  codedll = 'AnyQv.dll';

var
  XvidInited: Boolean;
  XvidHandle: THandle;
  encparam: xvid_enc_create_t;
  decparam: xvid_dec_create_t;

function  XVID_MAKE_VERSION(a,b,c: Integer): Integer;
begin
  Result := ((a and $ff) shl 16) or ((b and $ff) shl 8) or (c and $ff);
end;

function  XVID_VERSION_MAJOR(a: Integer): Byte;
begin
 result := (a shr 16) and $ff;
end;

function  XVID_VERSION_MINOR(a: Integer): Byte;
begin
  result := (a shr 8) and $ff;
end;

function  XVID_VERSION_PATCH(a: Integer): Byte;
begin
  result := (a shr 0) and $ff;
end;

function  XVID_MAKE_API(a,b: Integer): Integer;
begin
  result := ((a and $ff) shl 16) or ((b and $ff) shl 0);
end;

function  XVID_API_MAJOR(a: Integer): Integer;
begin
 result := (a shr 16) and $ff;
end;

function  XVID_API_MINOR(a: Integer): Integer;
begin
 result := (a shr 0) and $ff;
end;


//function xvid_global; external 'xvidcore.dll' name 'xvid_global';
//function xvid_decore; external 'xvidcore.dll' name 'xvid_decore';
//function xvid_encore; external 'xvidcore.dll' name 'xvid_encore';

function InitCodehandle(width:Integer= 160; height:Integer=120; rate:Integer=15): Boolean;
begin
  result := false;
  if not XvidInited then exit;

  FillMemory(@encparam, sizeof(encparam),0);
  encparam.version := XVID_VERSION;
  encparam.profile := XVID_PROFILE_ARTS_L1;
  encparam.width := width;
  encparam.height := height;
  encparam.max_key_interval := 300;

  if Vencodeproc(nil, XVID_ENC_CREATE, @encparam, nil) <> 0 then exit;
  ENCodehandle := encparam.handle;

  FillMemory(@decparam, sizeof(decparam),0);
  decparam.version := XVID_VERSION;

  if Vdecodeproc(nil, XVID_DEC_CREATE, @decparam, nil) <> 0 then
  begin
    DECodehandle := nil;
    exit;
  end;
  DECodehandle := decparam.handle;
  Result := true;
end;


function InitCode(width:Integer= 160; height:Integer=120; rate:Integer=15): boolean;
var
  xinit: xvid_gbl_init_t;
  initproc : xvid_global;
begin
  Result := CodeInited;
  if Result then
  begin
    UninitCode;
    Result := False;
  end;
  if XvidHandle <= 0 then
    XvidHandle := LoadLibrary(pchar(ExtractFilePath(Application.ExeName)+codedll));
  if XvidHandle <= 0 then
    exit;
  initproc := GetProcAddress(XvidHandle, 'xvid_global');
  Vdecodeproc := GetProcAddress(XvidHandle, 'xvid_decore');
  Vencodeproc := GetProcAddress(XvidHandle, 'xvid_encore');

  xinit.version := XVID_VERSION;
  xinit.cpu_flags := 0;
  xinit.debug := 0;
  XvidInited := initproc(nil, 0, @xinit, nil) = 0;
  Result := InitCodehandle(width, height, rate);
  if not Result then
    UninitCode;
  CodeInited := Result;
end;

function InitEnCode(width:Integer= 160; height:Integer=120; rate:Integer=15): boolean;
begin
  result := false;
  if not XvidInited then exit;

  Vencodeproc(ENCodehandle, XVID_ENC_DESTROY, nil, nil);
  FillMemory(@encparam, sizeof(encparam),0);
  encparam.version := XVID_VERSION;
  encparam.profile := XVID_PROFILE_ARTS_L1;
  encparam.width := width;
  encparam.height := height;
  encparam.max_key_interval := 300;

  if Vencodeproc(nil, XVID_ENC_CREATE, @encparam, nil) <> 0 then exit;
  ENCodehandle := encparam.handle;

  Result := true;
end;

procedure UnInitCode;
begin
  CodeInited := false;

  if assigned(Vencodeproc) and (ENCodehandle<>nil) then
    Vencodeproc(ENCodehandle, XVID_ENC_DESTROY, nil, nil);
  ENCodehandle := nil;
  Vencodeproc := nil;

  if assigned(Vdecodeproc) and (DECodehandle<>nil) then
    Vdecodeproc(DECodehandle, XVID_DEC_DESTROY, nil, nil);
  DECodehandle := nil;
  VDecodeproc := nil;

  if XvidHandle>0 then
    FreeLibrary(XvidHandle);
  XvidHandle := 0;
  XvidInited := false;
end;


initialization
  XVID_VERSION := XVID_MAKE_VERSION(1,0,0);
  XVID_API := XVID_MAKE_API(4, 0);

  XvidInited := false;
  CodeInited := false;
  ENCodehandle := nil;
  DECodehandle := nil;
  Vencodeproc := nil;
  VDecodeproc := nil;
  CurFRAMESize := -1;
  XvidHandle := 0;
end.
