Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

frames.h

Go to the documentation of this file.
00001 /*===========================================================================*
00002  * frames.h                                                                  *
00003  *                                                                           *
00004  *      stuff dealing with frames                                            *
00005  *                                                                           *
00006  *===========================================================================*/
00007 
00008 /*
00009  * Copyright (c) 1995 The Regents of the University of California.
00010  * All rights reserved.
00011  *
00012  * Permission to use, copy, modify, and distribute this software and its
00013  * documentation for any purpose, without fee, and without written agreement is
00014  * hereby granted, provided that the above copyright notice and the following
00015  * two paragraphs appear in all copies of this software.
00016  *
00017  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
00018  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
00019  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
00020  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00021  *
00022  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
00023  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
00024  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
00025  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
00026  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
00027  */
00028 
00029 /*  
00030  *  $Header: /misc/elrond0/share/cvs/AFNI/src/mpeg_encodedir/headers/frames.h,v 1.5 2004/04/02 15:12:41 rwcox Exp $
00031  *  $Log: frames.h,v $
00032  *  Revision 1.5  2004/04/02 15:12:41  rwcox
00033  *  Cput
00034  *
00035  *  Revision 1.4  2004/02/05 21:32:23  rwcox
00036  *  Cput
00037  *
00038  *  Revision 1.3  2003/12/23 13:50:08  rwcox
00039  *  Cput
00040  *
00041  *  Revision 1.2  2003/12/03 14:46:15  rwcox
00042  *  Cput
00043  *
00044  *  Revision 1.1  2001/12/17 18:25:44  rwcox
00045  *  Cadd
00046  *
00047  *  Revision 1.13  1995/08/15 23:43:04  smoot
00048  *  *** empty log message ***
00049  *
00050  * Revision 1.12  1995/04/14  23:13:18  smoot
00051  * Reorganized for better rate control.  Added overflow in DCT values
00052  * handling.
00053  *
00054  * Revision 1.11  1995/01/19  23:54:46  smoot
00055  * allow computediffdcts to un-assert parts of the pattern
00056  *
00057  * Revision 1.10  1995/01/16  07:43:10  eyhung
00058  * Added realQuiet
00059  *
00060  * Revision 1.9  1995/01/10  23:15:28  smoot
00061  * Fixed searchRange lack of def
00062  *
00063  * Revision 1.8  1994/11/15  00:55:36  smoot
00064  * added printMSE
00065  *
00066  * Revision 1.7  1994/11/14  22:51:02  smoot
00067  * added specifics flag.  Added BlockComputeSNR parameters
00068  *
00069  * Revision 1.6  1994/11/01  05:07:23  darryl
00070  *  with rate control changes added
00071  *
00072  * Revision 1.1  1994/09/27  01:02:55  darryl
00073  * Initial revision
00074  *
00075  * Revision 1.5  1993/07/22  22:24:23  keving
00076  * nothing
00077  *
00078  * Revision 1.4  1993/07/09  00:17:23  keving
00079  * nothing
00080  *
00081  * Revision 1.3  1993/06/03  21:08:53  keving
00082  * nothing
00083  *
00084  * Revision 1.2  1993/03/02  19:00:27  keving
00085  * nothing
00086  *
00087  * Revision 1.1  1993/02/19  20:15:51  keving
00088  * nothing
00089  *
00090  */
00091 
00092 
00093 #ifndef FRAMES_INCLUDED
00094 #define FRAMES_INCLUDED
00095 
00096 /*==============*
00097  * HEADER FILES *
00098  *==============*/
00099 
00100 #include "ansi.h"
00101 #include "mtypes.h"
00102 #include "mheaders.h"
00103 #include "frame.h"
00104 
00105 
00106 /*===========*
00107  * CONSTANTS *
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     /* motion vector stuff */
00128 #define FORW_F_CODE fCode           /* from picture header */
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  * STRUCTURE DEFINITIONS *
00142  *=======================*/
00143 
00144 typedef struct FrameTableStruct {
00145     /* the following are all initted once and never changed */
00146     /* (they depend only on the pattern */
00147     char typ;
00148     struct FrameTableStruct *next;
00149     struct FrameTableStruct *prev;
00150 
00151     /* nextOutput is a pointer to next frame table entry to output */
00152     struct FrameTableStruct *nextOutput;
00153 
00154     boolean     freeNow;        /* TRUE iff no frames point back to this */
00155 
00156     int number;
00157 
00158     int bFrameNumber;           /* actual frame number, if a b-frame */
00159     
00160 } FrameTable;
00161 
00162 
00163 /*==================*
00164  * TYPE DEFINITIONS *
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  * MACROS *
00179  *========*/
00180 
00181 #define FRAME_TYPE(num)     framePattern[num % framePatternLen]
00182 
00183 /* return ceiling(a/b) where a, b are ints, using temp value c */
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 /* assumes many things:
00188  * block indices are (y,x)
00189  * variables y_dc_pred, cr_dc_pred, and cb_dc_pred
00190  * flat block fb exists
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 /* pict_code_type */, mbAI /* addr_incr */,   \
00215                     qscale /* q_scale */,                                   \
00216                     0 /* forw_f_code */, 0 /* back_f_code */,               \
00217                     0 /* horiz_forw_r */, 0 /* vert_forw_r */,              \
00218                     0 /* horiz_back_r */, 0 /* vert_back_r */,              \
00219                     0 /* motion_forw */, 0 /* m_horiz_forw */,              \
00220                     0 /* m_vert_forw */, 0 /* motion_back */,               \
00221                     0 /* m_horiz_back */, 0 /* m_vert_back */,              \
00222                     0 /* mb_pattern */, TRUE /* mb_intra */);               \
00223                                                                             \
00224         /* Y blocks */                                                      \
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         /* CB block */                                                      \
00235         EncodeCDC(fb[4][0], &cb_dc_pred, bb);                               \
00236         Mpost_RLEHuffIBlock(fb[4], bb);                                     \
00237                                                                             \
00238         /* CR block */                                                      \
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  * EXTERNAL PROCEDURE prototypes *
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 /* DIFFERENCE FUNCTIONS */
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  * GLOBAL VARIABLES *
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;           /* shut up for at least quietTime seconds;
00382                                  * negative means shut up forever
00383                                  */
00384 extern boolean realQuiet;       /* TRUE = no messages to stdout */
00385 
00386 extern boolean frameSummary;    /* TRUE = frame summaries should be printed */
00387 extern boolean  printSNR;
00388 extern boolean  printMSE;
00389 extern boolean  decodeRefFrames;    /* TRUE = should decode I and P frames */
00390 extern int      fCodeI,fCodeP,fCodeB;
00391 extern boolean    forceEncodeLast;
00392 extern int TIME_RATE;
00393 
00394 #endif /* FRAMES_INCLUDED */
 

Powered by Plone

This site conforms to the following standards: