#ifndef _DECODER_H_
#define _DECODER_H_
#include "xvid.h"
#include "portab.h"
#include "global.h"
#include "image.h"
#include "vlc_codes.h"
#include "Interpolate8x8.h"
struct ESTIMATION {
int method;
int opaque;
int transparent;
int intra_cae;
int inter_cae;
int no_update;
int upsampling;
int intra_blocks;
int inter_blocks;
int inter4v_blocks;
int gmc_blocks;
int not_coded_blocks;
int dct_coefs;
int dct_lines;
int vlc_symbols;
int vlc_bits;
int apm;
int npm;
int interpolate_mc_q;
int forw_back_mc_q;
int halfpel2;
int halfpel4;
int sadct;
int quarterpel;
ESTIMATION() {
MemSet(this, 0, sizeof(ESTIMATION));
}
};
struct S_decoder {
private:
#ifdef PROFILE
mutable C_profiler &prof;
#endif
int Resize();
void SetEdges(IMAGE &img) const;
void I_Frame(Bitstream * bs, bool reduced_resolution, int quant, int intra_dc_threshold);
void P_Frame(Bitstream * bs, int rounding, bool reduced_resolution, int quant, int fcode, int intra_dc_threshold, const WARPPOINTS *const gmc_warp);
void MBIntra(MACROBLOCK *pMB, dword x_pos, dword y_pos, dword acpred_flag, dword cbp,
Bitstream *bs, dword quant, dword intra_dc_threshold, dword bound, bool reduced_resolution);
void mb_decode(const dword cbp, Bitstream * bs, byte * pY_Cur, byte * pU_Cur, byte * pV_Cur, bool reduced_resolution, const MACROBLOCK * pMB);
void DecodeInterMacroBlock(const MACROBLOCK *pMB, dword x_pos, dword y_pos, dword cbp, Bitstream *bs,
bool rounding, bool reduced_resolution, int ref);
void mbgmc(MACROBLOCK *pMB, dword x_pos, dword y_pos, dword fcode, dword cbp, Bitstream *bs, bool rounding);
void BFrameInterpolateMBInter(const IMAGE &forward, const IMAGE &backward, const MACROBLOCK *pMB, dword x_pos, dword y_pos, Bitstream *bs, int direct);
void B_Frame(Bitstream * bs, int quant, int fcode_forward, int fcode_backward);
void GetMotionVector(Bitstream *bs, int x, int y, int k, VECTOR *ret_mv, int fcode, int bound);
int read_video_packet_header(Bitstream *bs, const int addbits, int *quant, int *fcode_forward, int *fcode_backward, int *intra_dc_threshold);
void read_vol_complexity_estimation_header(Bitstream * bs);
int BitstreamReadHeaders(Bitstream * bs, bool &rounding, bool *reduced_resolution, dword *quant, dword *fcode_forward,
dword *fcode_backward, dword *intra_dc_threshold, WARPPOINTS *gmc_warp);
void read_vop_complexity_estimation_header(Bitstream * bs, int coding_type);
int get_coeff(Bitstream *bs, int *run, int *last, int intra, int short_video_header);
void get_intra_block(Bitstream * bs, int *block, int direction, int coeff);
void get_inter_block(Bitstream * bs, int *block, int direction);
void idct_int32_init();
void InverseDiscreteCosineTransform(int *block) const;
friend int decoder_create(xvid_dec_create_t *create);
int Init(xvid_dec_create_t *create);
#ifdef PROFILE
void interpolate8x8_quarterpel(byte *cur, byte *refn, byte *refh, byte *refv, byte *refhv, dword x, dword y, int dx, int dy, dword stride, bool rounding) {
::interpolate8x8_quarterpel(cur, refn, refh, refv, refhv, x, y, dx, dy, stride, rounding);
}
void interpolate16x16_switch(byte *cur, const byte *refn, dword x, dword y, int dx, int dy, dword stride, bool rounding) {
interpolate8x8_switch(cur, refn, x, y, dx, dy, stride, rounding);
interpolate8x8_switch(cur, refn, x+8, y, dx, dy, stride, rounding);
interpolate8x8_switch(cur, refn, x, y+8, dx, dy, stride, rounding);
interpolate8x8_switch(cur, refn, x+8, y+8, dx, dy, stride, rounding);
}
void interpolate8x8_switch(byte *cur, const byte *refn, dword x, dword y, int dx, int dy, dword stride, bool rounding) {
const byte *src = refn + ((y + (dy>>1)) * stride + x + (dx>>1));
byte *dst = cur + (y * stride + x);
int code = ((dx & 1) << 1) + (dy & 1);
switch(code) {
case 0:
transfer8x8_copy(dst, src, stride);
break;
case 1:
interpolate8x8_halfpel_v(dst, src, stride, rounding);
break;
case 2:
interpolate8x8_halfpel_h(dst, src, stride, rounding);
break;
default:
interpolate8x8_halfpel_hv(dst, src, stride, rounding);
break;
}
}
#endif
public:
S_decoder(xvid_dec_create_t *create);
~S_decoder();
int time_inc_resolution;
int fixed_time_inc;
dword time_inc_bits;
dword shape;
dword quant_bits;
dword quant_type;
dword *mpeg_quant_matrices;
int quarterpel;
int complexity_estimation_disable;
ESTIMATION estimation;
dword top_field_first;
dword alternate_vertical_scan;
int aspect_ratio;
int par_width;
int par_height;
int sprite_enable;
int sprite_warping_points;
int sprite_warping_accuracy;
int sprite_brightness_change;
bool interlacing;
bool newpred_enable;
bool reduced_resolution_enable;
int bs_version;
dword width;
dword height;
dword edged_width;
dword edged_height;
IMAGE cur;
IMAGE refn[2];
IMAGE tmp;
IMAGE qtmp;
dword mb_width;
dword mb_height;
MACROBLOCK *mbs;
MACROBLOCK *last_mbs;
int last_coding_type;
int frames;
VECTOR p_fmv, p_bmv;
int64_t time;
int64_t time_base;
int64_t last_time_base;
int64_t last_non_b_time;
dword time_pp;
dword time_bp;
bool fixed_dimensions;
bool scalability;
bool low_delay;
bool low_delay_default;
bool last_reduced_resolution;
bool packed_mode;
IMAGE gmc;
GMC_DATA gmc_data;
NEW_GMC_DATA new_gmc_data;
struct REVERSE_EVENT {
byte len;
EVENT event;
};
REVERSE_EVENT DCT3D[2][4096];
VLC coeff_VLC[2][2][64][64];
typedef int t_clip_val;
t_clip_val iclip[1024];
void init_vlc_tables();
int Decode(xvid_dec_frame_t * frame, xvid_dec_stats_t * stats);
};
void init_decoder(dword cpu_flags);
int decoder_create(xvid_dec_create_t * param);
#endif