00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 #ifndef FRAMES_INCLUDED
00094 #define FRAMES_INCLUDED
00095
00096
00097
00098
00099
00100 #include "ansi.h"
00101 #include "mtypes.h"
00102 #include "mheaders.h"
00103 #include "frame.h"
00104
00105
00106
00107
00108
00109
00110 #define I_FRAME 1
00111 #define P_FRAME 2
00112 #define B_FRAME 3
00113
00114 #define LUM_BLOCK 0
00115 #define CHROM_BLOCK 1
00116 #define CR_BLOCK 2
00117 #define CB_BLOCK 3
00118
00119 #define MOTION_FORWARD 0
00120 #define MOTION_BACKWARD 1
00121 #define MOTION_INTERPOLATE 2
00122
00123
00124 #define USE_HALF 0
00125 #define USE_FULL 1
00126
00127
00128 #define FORW_F_CODE fCode
00129 #define BACK_F_CODE fCode
00130 #define FORW_F (1 << (FORW_F_CODE - 1))
00131 #define BACK_F (1 << (BACK_F_CODE - 1))
00132 #define RANGE_NEG (-(1 << (3 + FORW_F_CODE)))
00133 #define RANGE_POS ((1 << (3 + FORW_F_CODE))-1)
00134 #define MODULUS (1 << (4 + FORW_F_CODE))
00135
00136 #define ORIGINAL_FRAME 0
00137 #define DECODED_FRAME 1
00138
00139
00140
00141
00142
00143
00144 typedef struct FrameTableStruct {
00145
00146
00147 char typ;
00148 struct FrameTableStruct *next;
00149 struct FrameTableStruct *prev;
00150
00151
00152 struct FrameTableStruct *nextOutput;
00153
00154 boolean freeNow;
00155
00156 int number;
00157
00158 int bFrameNumber;
00159
00160 } FrameTable;
00161
00162
00163
00164
00165
00166
00167 typedef struct dct_data_tye_struct {
00168 char useMotion;
00169 char pattern, mode;
00170 int fmotionX, fmotionY, bmotionX, bmotionY;
00171 } dct_data_type;
00172
00173 void EncodeYDC _ANSI_ARGS_((int32 dc_term, int32 *pred_term, BitBucket *bb));
00174 void EncodeCDC _ANSI_ARGS_((int32 dc_term, int32 *pred_term, BitBucket *bb));
00175
00176
00177
00178
00179
00180
00181 #define FRAME_TYPE(num) framePattern[num % framePatternLen]
00182
00183
00184 #define int_ceil_div(a,b,c) ((b*(c = a/b) < a) ? (c+1) : c)
00185 #define int_floor_div(a,b,c) ((b*(c = a/b) > a) ? (c-1) : c)
00186
00187
00188
00189
00190
00191
00192 #define GEN_I_BLOCK(frameType, frame, bb, mbAI, qscale) { \
00193 boolean overflow, overflowChange=FALSE; \
00194 int overflowValue = 0; \
00195 do { \
00196 overflow = Mpost_QuantZigBlock(dct[y][x], fb[0], \
00197 qscale, TRUE)==MPOST_OVERFLOW; \
00198 overflow |= Mpost_QuantZigBlock(dct[y][x+1], fb[1], \
00199 qscale, TRUE)==MPOST_OVERFLOW; \
00200 overflow |= Mpost_QuantZigBlock(dct[y+1][x], fb[2], \
00201 qscale, TRUE)==MPOST_OVERFLOW; \
00202 overflow |= Mpost_QuantZigBlock(dct[y+1][x+1], fb[3], \
00203 qscale, TRUE)==MPOST_OVERFLOW; \
00204 overflow |= Mpost_QuantZigBlock(dctb[y >> 1][x >> 1], \
00205 fb[4], qscale, TRUE)==MPOST_OVERFLOW; \
00206 overflow |= Mpost_QuantZigBlock(dctr[y >> 1][x >> 1], \
00207 fb[5], qscale, TRUE)==MPOST_OVERFLOW; \
00208 if ((overflow) && (qscale!=31)) { \
00209 overflowChange = TRUE; overflowValue++; \
00210 qscale++; \
00211 } else overflow = FALSE; \
00212 } while (overflow); \
00213 Mhead_GenMBHeader(bb, \
00214 frameType , mbAI , \
00215 qscale , \
00216 0 , 0 , \
00217 0 , 0 , \
00218 0 , 0 , \
00219 0 , 0 , \
00220 0 , 0 , \
00221 0 , 0 , \
00222 0 , TRUE ); \
00223 \
00224 \
00225 EncodeYDC(fb[0][0], &y_dc_pred, bb); \
00226 Mpost_RLEHuffIBlock(fb[0], bb); \
00227 EncodeYDC(fb[1][0], &y_dc_pred, bb); \
00228 Mpost_RLEHuffIBlock(fb[1], bb); \
00229 EncodeYDC(fb[2][0], &y_dc_pred, bb); \
00230 Mpost_RLEHuffIBlock(fb[2], bb); \
00231 EncodeYDC(fb[3][0], &y_dc_pred, bb); \
00232 Mpost_RLEHuffIBlock(fb[3], bb); \
00233 \
00234 \
00235 EncodeCDC(fb[4][0], &cb_dc_pred, bb); \
00236 Mpost_RLEHuffIBlock(fb[4], bb); \
00237 \
00238 \
00239 EncodeCDC(fb[5][0], &cr_dc_pred, bb); \
00240 Mpost_RLEHuffIBlock(fb[5], bb); \
00241 if (overflowChange) qscale -= overflowValue; \
00242 }
00243
00244 #define BLOCK_TO_FRAME_COORD(bx1, bx2, x1, x2) { \
00245 x1 = (bx1)*DCTSIZE; \
00246 x2 = (bx2)*DCTSIZE; \
00247 }
00248
00249 #define MOTION_TO_FRAME_COORD(bx1, bx2, mx1, mx2, x1, x2) { \
00250 x1 = (bx1)*DCTSIZE+(mx1); \
00251 x2 = (bx2)*DCTSIZE+(mx2); \
00252 }
00253
00254 #define COORD_IN_FRAME(fy,fx, type) \
00255 ((type == LUM_BLOCK) ? \
00256 ((fy >= 0) && (fx >= 0) && (fy < Fsize_y) && (fx < Fsize_x)) : \
00257 ((fy >= 0) && (fx >= 0) && (fy < (Fsize_y>>1)) && (fx < (Fsize_x>>1))))
00258
00259 #define ENCODE_MOTION_VECTOR(x,y,xq, yq, xr, yr, f) { \
00260 int tempC; \
00261 \
00262 if ( x < RANGE_NEG ) tempX = x + MODULUS; \
00263 else if ( x > RANGE_POS ) tempX = x - MODULUS; \
00264 else tempX = x; \
00265 \
00266 if ( y < RANGE_NEG ) tempY = y + MODULUS; \
00267 else if ( y > RANGE_POS ) tempY = y - MODULUS; \
00268 else tempY = y; \
00269 \
00270 if ( tempX >= 0 ) { \
00271 xq = int_ceil_div(tempX, f, tempC); \
00272 xr = f - 1 + tempX - xq*f; \
00273 } else { \
00274 xq = int_floor_div(tempX, f, tempC); \
00275 xr = f - 1 - tempX + xq*f; \
00276 } \
00277 \
00278 if ( tempY >= 0 ) { \
00279 yq = int_ceil_div(tempY, f, tempC); \
00280 yr = f - 1 + tempY - yq*f; \
00281 } else { \
00282 yq = int_floor_div(tempY, f, tempC); \
00283 yr = f - 1 - tempY + yq*f; \
00284 } \
00285 }
00286
00287
00288 #define DoQuant(bit, src, dest) \
00289 if (pattern & bit) { \
00290 switch (Mpost_QuantZigBlock(src, dest, QScale, FALSE)) { \
00291 case MPOST_NON_ZERO: \
00292 break; \
00293 case MPOST_ZERO: \
00294 pattern ^= bit; \
00295 break; \
00296 case MPOST_OVERFLOW: \
00297 if (QScale != 31) { \
00298 QScale++; \
00299 overflowChange = TRUE; \
00300 overflowValue++; \
00301 goto calc_blocks; \
00302 } \
00303 break; \
00304 } \
00305 }
00306
00307
00308
00309
00310
00311 void ComputeBMotionLumBlock _ANSI_ARGS_((MpegFrame *prev, MpegFrame *next,
00312 int by, int bx, int mode, int fmy, int fmx,
00313 int bmy, int bmx, LumBlock motionBlock));
00314 int BMotionSearch _ANSI_ARGS_((LumBlock currentBlock, MpegFrame *prev, MpegFrame *next,
00315 int by, int bx, int *fmy, int *fmx, int *bmy, int *bmx, int oldMode));
00316
00317
00318 void ComputeDiffDCTs _ANSI_ARGS_((MpegFrame *current, MpegFrame *prev, int by, int bx,
00319 int my, int mx, int *pattern));
00320 int ComputeDiffDCTBlock _ANSI_ARGS_((Block current, Block dest, Block motionBlock));
00321 void ComputeMotionBlock _ANSI_ARGS_((uint8 **prev, int by, int bx, int my, int mx,
00322 Block motionBlock));
00323 void ComputeMotionLumBlock _ANSI_ARGS_((MpegFrame *prevFrame, int by,
00324 int bx, int my, int mx,
00325 LumBlock motionBlock));
00326 int32 ComputeBlockMAD _ANSI_ARGS_((Block current, Block prev));
00327
00328 void GenIFrame _ANSI_ARGS_((BitBucket *bb, MpegFrame *mf));
00329 void GenPFrame _ANSI_ARGS_((BitBucket *bb, MpegFrame *current, MpegFrame *prev));
00330 void GenBFrame _ANSI_ARGS_((BitBucket *bb, MpegFrame *curr, MpegFrame *prev, MpegFrame *next));
00331 void AllocDctBlocks _ANSI_ARGS_((void ));
00332
00333 float ShowIFrameSummary _ANSI_ARGS_((int inputFrameBits, int32 totalBits, FILE *fpointer));
00334 float ShowPFrameSummary _ANSI_ARGS_((int inputFrameBits, int32 totalBits, FILE *fpointer));
00335 float ShowBFrameSummary _ANSI_ARGS_((int inputFrameBits, int32 totalBits, FILE *fpointer));
00336
00337
00338
00339
00340 int32 LumBlockMAD _ANSI_ARGS_((LumBlock currentBlock, LumBlock motionBlock, int32 bestSoFar));
00341 int32 LumBlockMSE _ANSI_ARGS_((LumBlock currentBlock, LumBlock motionBlock, int32 bestSoFar));
00342 int32 LumMotionError _ANSI_ARGS_((LumBlock currentBlock, MpegFrame *prev,
00343 int by, int bx, int my, int mx,
00344 int32 bestSoFar));
00345 int32 LumAddMotionError _ANSI_ARGS_((LumBlock currentBlock,
00346 LumBlock blockSoFar, MpegFrame *prev,
00347 int by, int bx, int my, int mx,
00348 int32 bestSoFar));
00349 int32 LumMotionErrorA _ANSI_ARGS_((LumBlock current, MpegFrame *prevFrame,
00350 int by, int bx, int my, int mx,
00351 int32 bestSoFar));
00352 int32 LumMotionErrorB _ANSI_ARGS_((LumBlock current, MpegFrame *prevFrame,
00353 int by, int bx, int my, int mx,
00354 int32 bestSoFar));
00355 int32 LumMotionErrorC _ANSI_ARGS_((LumBlock current, MpegFrame *prevFrame,
00356 int by, int bx, int my, int mx,
00357 int32 bestSoFar));
00358 int32 LumMotionErrorD _ANSI_ARGS_((LumBlock current, MpegFrame *prevFrame,
00359 int by, int bx, int my, int mx,
00360 int32 bestSoFar));
00361 int32 LumMotionErrorSubSampled _ANSI_ARGS_((LumBlock currentBlock, MpegFrame *prevFrame,
00362 int by, int bx, int my, int mx,
00363 int startY, int startX));
00364 void BlockComputeSNR _ANSI_ARGS_((MpegFrame *current,
00365 float *snr, float *psnr));
00366 int32 time_elapsed _ANSI_ARGS_((void));
00367 void AllocDctBlocks _ANSI_ARGS_((void));
00368
00369
00370
00371
00372
00373 extern int pixelFullSearch;
00374 extern int searchRangeP,searchRangeB;
00375 extern int qscaleI;
00376 extern int gopSize;
00377 extern int slicesPerFrame;
00378 extern int blocksPerSlice;
00379 extern int referenceFrame;
00380 extern int specificsOn;
00381 extern int quietTime;
00382
00383
00384 extern boolean realQuiet;
00385
00386 extern boolean frameSummary;
00387 extern boolean printSNR;
00388 extern boolean printMSE;
00389 extern boolean decodeRefFrames;
00390 extern int fCodeI,fCodeP,fCodeB;
00391 extern boolean forceEncodeLast;
00392 extern int TIME_RATE;
00393
00394 #endif