/***************************************************************** * tmn (TMN encoder) * Copyright (C) 1995 Telenor R&D * Karl Olav Lillevold * * *****************************************************************/ /********************************************************************** * * Headerfile for TMN4 coder * Type definitions and declaration of functions * Date last modified: every now and then * **********************************************************************/ #include #include #include #include #include "config.h" #include"macros.h" /* This should not be changed */ #define MB_SIZE 16 /* If someone forgets to define a coding format, QCIF is default */ #if (!defined SQCIF && !defined QCIF && !defined CIF && !defined CIF4 && !defined CIF16) #define QCIF #endif /* The coding format is decided here. */ #ifdef SQCIF #define DEF_PELS 128 #define DEF_LINES 96 #endif #ifdef QCIF #define DEF_PELS 176 #define DEF_LINES 144 #endif #ifdef CIF #define DEF_PELS 352 #define DEF_LINES 288 #endif #ifdef CIF4 #define DEF_PELS 704 #define DEF_LINES 576 #endif #ifdef CIF16 #define DEF_PELS 1408 #define DEF_LINES 1152 #endif #define MBC DEF_PELS/MB_SIZE #define MBR DEF_LINES/MB_SIZE /* Parameters from TMN */ #define PREF_NULL_VEC 100 #define PREF_16_VEC 100 #define PREF_PBDELTA_NULL_VEC 50 int headerlength; /* Global variables */ int pels; int cpels; int lines; int trace; int advanced; int mv_outside_frame; int target_framerate; FILE *tf; /****************************/ #define PSC 1 #define PSC_LENGTH 17 #define ESCAPE 7167 #define PCT_INTER 1 #define PCT_INTRA 0 #define ON 1 #define OFF 0 #define SF_SQCIF 1 /* 001 */ #define SF_QCIF 2 /* 010 */ #define SF_CIF 3 /* 011 */ #define SF_4CIF 4 /* 100 */ #define SF_16CIF 5 /* 101 */ #define MODE_INTER 0 #define MODE_INTER_Q 1 #define MODE_INTER4V 2 #define MODE_INTRA 3 #define MODE_INTRA_Q 4 #define PBMODE_NORMAL 0 #define PBMODE_MVDB 1 #define PBMODE_CBPB_MVDB 2 #define QMODE_PI 0 #define QMODE_PB 1 #define NO_VEC 999 /* Motionvector structure */ typedef struct motionvector { int x; /* Horizontal comp. of mv */ int y; /* Vertical comp. of mv */ int x_half; /* Horizontal half-pel acc. */ int y_half; /* Vertical half-pel acc. */ int min_error; /* Min error for this vector */ int Mode; /* Necessary for adv. pred. mode */ } MotionVector; /* Point structure */ typedef struct point { int x; int y; } Point; /* Structure with image data */ typedef struct pict_image { unsigned char *lum; /* Luminance plane */ unsigned char *Cr; /* Cr plane */ unsigned char *Cb; /* Cb plane */ } PictImage; /* Group of pictures structure. */ /* Picture structure */ typedef struct pict { int prev; int curr; int TR; /* Time reference */ int source_format; int picture_coding_type; int spare; int mv_outside_frame; int syntax_arith_coding; int adv_pred_mode; int PB; int QUANT; int DQUANT; int MB; int seek_dist; /* Motion vector search window */ int use_gobsync; /* flag for gob_sync */ int MODB; /* B-frame mode */ int BQUANT; /* which quantizer to use for B-MBs in PB-frame */ int TRB; /* Time reference for B-picture */ int frame_inc; /* buffer control frame_inc */ float src_frame_rate; /* source material frame rate */ float bit_rate; float QP_mean; /* mean quantizer */ } Pict; int pic_type; /* Slice structure */ typedef struct slice { unsigned int vert_pos; /* Vertical position of slice */ unsigned int quant_scale; /* Quantization scale */ } Slice; /* Macroblock structure */ typedef struct macroblock { int mb_address; /* Macroblock address */ int macroblock_type; /* Macroblock type */ int skipped; /* 1 if skipped */ MotionVector motion; /* Motion Vector */ } Macroblock; /* Structure for macroblock data */ typedef struct mb_structure { int lum[16][16]; int Cr[8][8]; int Cb[8][8]; } MB_Structure; /* Structure for counted bits */ typedef struct bits_counted { int Y; int C; int vec; int CBPY; int CBPCM; int MODB; int CBPB; int COD; int header; int DQUANT; int total; int no_inter; int no_inter4v; int no_intra; /* NB: Remember to change AddBits(), ZeroBits() and AddBitsPicture() when entries are added here */ } Bits; /* Structure for data for data from previous macroblock */ /* Structure for average results and virtal buffer data */ typedef struct results { float SNR_l; /* SNR for luminance */ float SNR_Cr; /* SNR for chrominance */ float SNR_Cb; float QP_mean; /* Mean quantizer */ } Results; void Help(); void PrintSNR(Results *res, int num); void PrintResult(Bits *bits, int num); unsigned char *ReadImage(char *filename, int frame_no, int headerlength); PictImage *FillImage(unsigned char *in); void WriteImage(PictImage *image, char *filename); PictImage *InitImage(int size); void FreeImage(PictImage *image); char *StripName(char *s); int *MB_Encode(MB_Structure *mb_orig, int QP, int I, int qmode); int MB_Decode(int *qcoeff, MB_Structure *mb_recon, int QP, int I); int Dct( int *block, int *coeff); int idct(int *coeff,int *block); void FillLumBlock( int x, int y, PictImage *image, MB_Structure *data); void FillChromBlock(int x_curr, int y_curr, PictImage *image, MB_Structure *data); void ReconImage (int i, int j, MB_Structure *data, PictImage *recon); void CodeOneOrTwo(PictImage *curr, PictImage *B_image, PictImage *prev, PictImage *prev_recon, int QP, int frameskip, Bits *bits, Pict *pic, PictImage *B_recon, PictImage *recon); PictImage *CodeOneIntra(PictImage *curr, int QP, Bits *bits, Pict *pic); void Dequant(int *qcoeff, int *rcoeff, int QP, int I); void Quant(int *coeff, int *qcoeff, int QP, int I, int qmode); void CountBitsCoeff(int *qcoeff, int I, int CBP, Bits *bits, int ncoeffs); int CodeCoeff(int Mode, int *qcoeff, int block, int ncoeffs); int FindCBP(int *qcoeff, int Mode, int ncoeffs); void CountBitsVectors(MotionVector *MV[5][MBR+1][MBC+2], Bits *bits, int i, int j, int Mode, int newgob, Pict *pic); void FindPMV(MotionVector *MV[5][MBR+1][MBC+2], int x, int y, int *p0, int *p1, int block, int newgob); void ZeroBits(Bits *bits); void ZeroRes(Results *res); void ZeroVec(MotionVector *MV); void MarkVec(MotionVector *MV); void CopyVec(MotionVector *MV1, MotionVector *MV2); int EqualVec(MotionVector *MV2, MotionVector *MV1); void AddBits(Bits *total, Bits *bits); void AddRes(Results *total, Results *res, Pict *pic); void AddBitsPicture(Bits *bits); void FindMB(int x, int y, unsigned char *image, int MB[16][16]); MB_Structure *MB_Recon(PictImage *prev_recon, MB_Structure *diff, int x_curr, int y_curr, MotionVector *MV); MB_Structure *Predict(PictImage *curr, PictImage *prev_recon, int x_curr, int y_curr, MotionVector *MV); unsigned char *InterpolateImage(unsigned char *image, int w, int h); void MotionEstimatePicture(unsigned char *curr, unsigned char *prev, unsigned char *prev_ipol, int seek_dist, MotionVector *MV[5][MBR+1][MBC+2]); void MotionEstimation(unsigned char *curr, unsigned char *prev, int x_curr, int y_curr, int seek_dist, MotionVector *MV[5][MBR+1][MBC+2]); unsigned char *LoadArea(unsigned char *im, int x, int y, int x_size, int y_size, int lx); int SAD_Macroblock(unsigned char *ii, unsigned char *act_block, int h_length, int Min_FRAME); int SAD_Block(unsigned char *ii, unsigned char *act_block, int h_length, int min_sofar); int SAD_MB_integer(int *ii, int *act_block, int h_length, int min_sofar); MB_Structure *Predict_P(PictImage *curr_image, PictImage *prev_image, unsigned char *prev_ipol,int x_curr, int y_curr, MotionVector *fr[5][MBR+1][MBC+2]); MB_Structure *Predict_B(PictImage *curr_image, PictImage *prev_image, unsigned char *prev_ipol,int x_curr, int y_curr, MotionVector *fr[5][MBR+1][MBC+2], MB_Structure *recon_P, int TR,int TRB); void Clip(MB_Structure *data); void FindForwLumPredPB(unsigned char *prev_ipol, int x_curr, int y_curr, MotionVector *fr, int *pred, int TRD, int TRB, int bdx, int bdy, int bs, int comp); void FindBiDirLumPredPB(int *recon_P, MotionVector *fr, int *pred, int TRD, int TRB, int bdx, int bdy, int nh, int nv); void FindBiDirChrPredPB(MB_Structure *recon_P, int dx, int dy, MB_Structure *pred); void FindBiDirLimits(int vec, int *start, int *stop, int nhv); void FindBiDirChromaLimits(int vec, int *start, int *stop); void BiDirPredBlock(int xstart, int xstop, int ystart, int ystop, int xvec, int yvec, int *recon, int *pred, int bl); void DoPredChrom_P(int x_curr, int y_curr, int dx, int dy, PictImage *curr, PictImage *prev, MB_Structure *pred_error); void FindHalfPel(int x, int y, MotionVector *MV, unsigned char *prev, int *curr, int bs, int comp); void FindPred(int x, int y, MotionVector *fr, unsigned char *prev, int *pred, int bs, int comp); void FindPredOBMC(int x, int y, MotionVector *MV[5][MBR+1][MBC+2], unsigned char *prev, int *pred, int comp); MB_Structure *MB_Recon_P(PictImage *prev_image, unsigned char *prev_ipol, MB_Structure *diff, int x_curr, int y_curr, MotionVector *MV[5][MBR+1][MBC+2]); MB_Structure *MB_Recon_B(PictImage *prev, MB_Structure *diff, unsigned char *prev_ipol,int x_curr, int y_curr, MotionVector *MV[5][MBR+1][MBC+2], MB_Structure *recon_P,int TR, int TRB); void ReconLumBlock_P(int x, int y, MotionVector *fr, unsigned char *prev, int *data,int bs,int comp); void ReconChromBlock_P(int x_curr, int y_curr, int dx, int dy, PictImage *prev, MB_Structure *data); void FindChromBlock_P(int x_curr, int y_curr, int dx, int dy, PictImage *prev, MB_Structure *data); void ComputeSNR(PictImage *im1, PictImage *im2, Results *res, int write); void ZeroMBlock(MB_Structure *data); int CountBitsPicture(Pict *pic); void CountBitsMB(int Mode, int COD, int CBP, int CBPB, Pict *pic, Bits *bits); int CountBitsSlice(int slice, int quant); int ChooseMode(unsigned char *curr, int x_pos, int y_pos, int min_SAD); int ModifyMode(int Mode, int dquant); int *InterleaveCoeff(int *qp, int *qb, int bs); void MakeEdgeImage(unsigned char *src, unsigned char *dst, int width, int height, int edge); /* The following Routines are added for Rate Control */ void InitializePictureRate(float QP_mean, int pict_type, float bit_rate, int src_frame_rate, int bitcount); int UpdateQuantizer( int mb, float QP_mean, int pict_type, float bit_rate, int mb_width, int mb_height, int bitcount); int UpdatePictureRate(int pict_type, float bit_rate, int src_frame_rate, int bitcount); #ifndef FASTIDCT /* global declarations for idctref */ void init_idctref (void); void idctref (int *coeff, int *block); #endif /* Syntax based arithmetic coding routines */ void Count_sac_BitsCoeff(int *qcoeff, int I, int CBP, Bits *bits, int ncoeffs); int Code_sac_Coeff(int Mode, int *qcoeff, int block, int ncoeffs); int CodeTCoef(int mod_index, int position, int intra); void Count_sac_BitsVectors(MotionVector *MV[5][MBR+1][MBC+2], Bits *bits, int i, int j, int Mode, int newgob, Pict *pic); void Count_sac_BitsMB(int Mode,int COD,int CBP,int CBPB,Pict *pic,Bits *bits); int AR_Encode(int index, int cumul_freq[]); int indexfn(int value, int table[], int max); int bit_opp_bits(int); void bit_in_psc_layer(int); int encoder_flush(); /* Fix broken header-files on suns to avoid compiler warnings */ /* #define BROKEN_SUN_HEADERS here or in Makefile */ #ifdef BROKEN_SUN_HEADERS extern int printf(); extern int fprintf(); extern int time(); extern int fclose(); extern int rewind(); extern int fseek(); extern int fread(); extern int fwrite(); extern int fflush(); extern int fscanf(); extern int _flsbuf(); extern int _filbuf(); #endif