home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 9 / CD_ASCQ_09_1193.iso / news / 4441 / mpegcode / src / headers / frames.h < prev    next >
C/C++ Source or Header  |  1993-09-27  |  11KB  |  309 lines

  1. /*===========================================================================*
  2.  * frames.h                                     *
  3.  *                                         *
  4.  *    stuff dealing with frames                         *
  5.  *                                         *
  6.  *===========================================================================*/
  7.  
  8. /*
  9.  * Copyright (c) 1993 The Regents of the University of California.
  10.  * All rights reserved.
  11.  *
  12.  * Permission to use, copy, modify, and distribute this software and its
  13.  * documentation for any purpose, without fee, and without written agreement is
  14.  * hereby granted, provided that the above copyright notice and the following
  15.  * two paragraphs appear in all copies of this software.
  16.  *
  17.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  18.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  19.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  20.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  21.  *
  22.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  23.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  24.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  25.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  26.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  27.  */
  28.  
  29. /*  
  30.  *  $Header: /n/picasso/users/keving/encode/src/headers/RCS/frames.h,v 1.5 1993/07/22 22:24:23 keving Exp keving $
  31.  *  $Log: frames.h,v $
  32.  * Revision 1.5  1993/07/22  22:24:23  keving
  33.  * nothing
  34.  *
  35.  * Revision 1.4  1993/07/09  00:17:23  keving
  36.  * nothing
  37.  *
  38.  * Revision 1.3  1993/06/03  21:08:53  keving
  39.  * nothing
  40.  *
  41.  * Revision 1.2  1993/03/02  19:00:27  keving
  42.  * nothing
  43.  *
  44.  * Revision 1.1  1993/02/19  20:15:51  keving
  45.  * nothing
  46.  *
  47.  */
  48.  
  49.  
  50. /*==============*
  51.  * HEADER FILES *
  52.  *==============*/
  53.  
  54. #include "ansi.h"
  55. #include "mtypes.h"
  56. #include "mheaders.h"
  57. #include "frame.h"
  58.  
  59.  
  60. /*===========*
  61.  * CONSTANTS *
  62.  *===========*/
  63.  
  64. #define I_FRAME    1
  65. #define P_FRAME 2
  66. #define    B_FRAME    3
  67.  
  68. #define LUM_BLOCK   0
  69. #define    CHROM_BLOCK 1
  70. #define    CR_BLOCK    2
  71. #define CB_BLOCK    3
  72.  
  73. #define    MOTION_FORWARD        0
  74. #define MOTION_BACKWARD        1
  75. #define MOTION_INTERPOLATE  2
  76.  
  77.  
  78. #define USE_HALF    0
  79. #define    USE_FULL    1
  80.  
  81.     /* motion vector stuff */
  82. #define FORW_F_CODE fCode        /* from picture header */
  83. #define BACK_F_CODE fCode
  84. #define FORW_F    (1 << (FORW_F_CODE - 1))
  85. #define    BACK_F    (1 << (BACK_F_CODE - 1))
  86. #define RANGE_NEG    (-(1 << (3 + FORW_F_CODE)))
  87. #define RANGE_POS    ((1 << (3 + FORW_F_CODE))-1)
  88. #define MODULUS        (1 << (4 + FORW_F_CODE))
  89.  
  90. #define ORIGINAL_FRAME    0
  91. #define DECODED_FRAME    1
  92.  
  93.  
  94. /*=======================*
  95.  * STRUCTURE DEFINITIONS *
  96.  *=======================*/
  97.  
  98. typedef    struct FrameTableStruct {
  99.     MpegFrame *frame;        /* this changes during execution */
  100.  
  101.     /* the following are all initted once and never changed */
  102.     /* (they depend only on the pattern */
  103.  
  104.     struct FrameTableStruct *next;
  105.     struct FrameTableStruct *prev;
  106.  
  107.     /* nextOutput is a pointer to next frame table entry to output */
  108.     struct FrameTableStruct *nextOutput;
  109.  
  110.     boolean    freeNow;    /* TRUE iff no frames point back to this */
  111.  
  112.     int number;
  113.  
  114.     int    bFrameNumber;        /* actual frame number, if a b-frame */
  115.     
  116. } FrameTable;
  117.  
  118.  
  119. /*==================*
  120.  * TYPE DEFINITIONS *
  121.  *==================*/
  122.  
  123.     /* none */
  124.  
  125.  
  126. void    EncodeYDC _ANSI_ARGS_((int16 dc_term, int32 *pred_term, BitBucket *bb));
  127. void EncodeCDC _ANSI_ARGS_((int16 dc_term, int32 *pred_term, BitBucket *bb));
  128.  
  129.  
  130. /*========*
  131.  * MACROS *
  132.  *========*/
  133.  
  134. #define FRAME_TYPE(num)        framePattern[num % framePatternLen]
  135.  
  136. /* return ceiling(a/b) where a, b are ints, using temp value c */
  137. #define int_ceil_div(a,b,c)   ((b*(c = a/b) < a) ? (c+1) : c)
  138. #define int_floor_div(a,b,c)    ((b*(c = a/b) > a) ? (c-1) : c)
  139.  
  140.  
  141. #define COMPUTE_BLOCK(block, qscale, n) {            \
  142.     Mpost_QuantZigBlock(block, fb[n], qscale, TRUE);    \
  143.     EncodeYDC(fb[n][0], &y_dc_pred, bb);            \
  144.     Mpost_RLEHuffIBlock(fb[n], bb);                \
  145.     }
  146.  
  147.  
  148.  
  149. /* assumes many things:
  150.  * block indices are (y,x)
  151.  * variables y_dc_pred, cr_dc_pred, and cb_dc_pred
  152.  * flat block fb exists
  153.  */
  154. #define    GEN_I_BLOCK(frameType, frame, bb, mbAI, qscale)    {            \
  155.     Mhead_GenMBHeader(bb,                            \
  156.             frameType /* pict_code_type */, mbAI /* addr_incr */,   \
  157.             0 /* mb_quant */, 0 /* q_scale */,                \
  158.             0 /* forw_f_code */, 0 /* back_f_code */,            \
  159.             0 /* horiz_forw_r */, 0 /* vert_forw_r */,            \
  160.             0 /* horiz_back_r */, 0 /* vert_back_r */,            \
  161.             0 /* motion_forw */, 0 /* m_horiz_forw */,            \
  162.             0 /* m_vert_forw */, 0 /* motion_back */,            \
  163.             0 /* m_horiz_back */, 0 /* m_vert_back */,            \
  164.             0 /* mb_pattern */, 1 /* mb_intra */);            \
  165.                                         \
  166.     /* Y blocks */                                \
  167.     COMPUTE_BLOCK(frame->y_blocks[y][x], qscale, 0);                \
  168.     COMPUTE_BLOCK(frame->y_blocks[y][x+1], qscale, 1);                \
  169.     COMPUTE_BLOCK(frame->y_blocks[y+1][x], qscale, 2);                \
  170.     COMPUTE_BLOCK(frame->y_blocks[y+1][x+1], qscale, 3);            \
  171.                                         \
  172.     /* CB block */                                \
  173.     Mpost_QuantZigBlock(frame->cb_blocks[y >> 1][x >> 1], fb[4], qscale, TRUE); \
  174.     EncodeCDC(fb[4][0], &cb_dc_pred, bb);                        \
  175.     Mpost_RLEHuffIBlock(fb[4], bb);                        \
  176.                                         \
  177.     /* CR block */                                \
  178.     Mpost_QuantZigBlock(frame->cr_blocks[y >> 1][x >> 1], fb[5], qscale, TRUE); \
  179.     EncodeCDC(fb[5][0], &cr_dc_pred, bb);                        \
  180.     Mpost_RLEHuffIBlock(fb[5], bb);                        \
  181.     }
  182.  
  183.  
  184. #define    BLOCK_TO_FRAME_COORD(bx1, bx2, x1, x2) {    \
  185.     x1 = (bx1)*DCTSIZE;                \
  186.     x2 = (bx2)*DCTSIZE;                \
  187.     }
  188.  
  189. #define MOTION_TO_FRAME_COORD(bx1, bx2, mx1, mx2, x1, x2) { \
  190.     x1 = (bx1)*DCTSIZE+(mx1);                \
  191.     x2 = (bx2)*DCTSIZE+(mx2);                \
  192.     }
  193.  
  194. #define COORD_IN_FRAME(fy,fx, type)                    \
  195.     ((type == LUM_BLOCK) ?                        \
  196.      ((fy >= 0) && (fx >= 0) && (fy < Fsize_y) && (fx < Fsize_x)) :    \
  197.      ((fy >= 0) && (fx >= 0) && (fy < Fsize_y/2) && (fx < Fsize_x/2)))
  198.  
  199. #define ENCODE_MOTION_VECTOR(x,y,xq, yq, xr, yr, f) {            \
  200.     int    tempC;                            \
  201.                                     \
  202.     if ( x < RANGE_NEG )        tempX = x + MODULUS;        \
  203.     else if ( x > RANGE_POS ) tempX = x - MODULUS;            \
  204.     else                    tempX = x;            \
  205.                                     \
  206.     if ( y < RANGE_NEG )        tempY = y + MODULUS;        \
  207.     else if ( y > RANGE_POS ) tempY = y - MODULUS;            \
  208.     else                    tempY = y;            \
  209.                                     \
  210.     if ( tempX >= 0 ) {                        \
  211.         xq = int_ceil_div(tempX, f, tempC);                \
  212.         xr = f - 1 + tempX - xq*f;                    \
  213.     } else {                            \
  214.         xq = int_floor_div(tempX, f, tempC);            \
  215.         xr = f - 1 - tempX + xq*f;                    \
  216.     }                                \
  217.                                     \
  218.     if ( tempY >= 0 ) {                        \
  219.         yq = int_ceil_div(tempY, f, tempC);                \
  220.         yr = f - 1 + tempY - yq*f;                    \
  221.     } else {                            \
  222.         yq = int_floor_div(tempY, f, tempC);            \
  223.         yr = f - 1 - tempY + yq*f;                    \
  224.     }                                \
  225.     }
  226.  
  227.  
  228. /*===============================*
  229.  * EXTERNAL PROCEDURE prototypes *
  230.  *===============================*/
  231.  
  232. void    ComputeBMotionLumBlock _ANSI_ARGS_((MpegFrame *prev, MpegFrame *next,
  233.                    int by, int bx, int mode, int fmy, int fmx,
  234.                    int bmy, int bmx, LumBlock motionBlock));
  235. int    BMotionSearch _ANSI_ARGS_((LumBlock currentBlock, MpegFrame *prev, MpegFrame *next,
  236.               int by, int bx, int *fmy, int *fmx, int *bmy, int *bmx, int oldMode));
  237.  
  238.  
  239. void    ComputeDiffDCTs _ANSI_ARGS_((MpegFrame *current, MpegFrame *prev, int by, int bx,
  240.             int my, int mx, int pattern));
  241. void    ComputeDiffDCTBlock _ANSI_ARGS_((Block current, Block motionBlock));
  242. void    ComputeMotionBlock _ANSI_ARGS_((uint8 **prev, int by, int bx, int my, int mx,
  243.                Block motionBlock));
  244. void    ComputeMotionLumBlock _ANSI_ARGS_((MpegFrame *prevFrame, int by,
  245.                        int bx, int my, int mx,
  246.                        LumBlock motionBlock));
  247. int32    ComputeBlockMAD _ANSI_ARGS_((Block current, Block prev));
  248.  
  249. void    GenIFrame _ANSI_ARGS_((BitBucket *bb, MpegFrame *mf));
  250. void    GenPFrame _ANSI_ARGS_((BitBucket *bb, MpegFrame *current, MpegFrame *prev));
  251. void    GenBFrame _ANSI_ARGS_((BitBucket *bb, MpegFrame *curr, MpegFrame *prev, MpegFrame *next));
  252.  
  253. void    ShowIFrameSummary _ANSI_ARGS_((int inputFrameBits, int32 totalBits, FILE *fpointer));
  254. void    ShowPFrameSummary _ANSI_ARGS_((int inputFrameBits, int32 totalBits, FILE *fpointer));
  255. void    ShowBFrameSummary _ANSI_ARGS_((int inputFrameBits, int32 totalBits, FILE *fpointer));
  256.  
  257.  
  258. /* DIFFERENCE FUNCTIONS */
  259.  
  260. int32    LumBlockMAD _ANSI_ARGS_((LumBlock currentBlock, LumBlock motionBlock, int32 bestSoFar));
  261. int32    LumBlockMSE _ANSI_ARGS_((LumBlock currentBlock, LumBlock motionBlock, int32 bestSoFar));
  262. int32    LumMotionError _ANSI_ARGS_((LumBlock currentBlock, MpegFrame *prev,
  263.                     int by, int bx, int my, int mx,
  264.                     int32 bestSoFar));
  265. int32    LumAddMotionError _ANSI_ARGS_((LumBlock currentBlock,
  266.                        LumBlock blockSoFar, MpegFrame *prev,
  267.                        int by, int bx, int my, int mx,
  268.                        int32 bestSoFar));
  269. int32    LumMotionErrorA _ANSI_ARGS_((LumBlock current, MpegFrame *prevFrame,
  270.                      int by, int bx, int my, int mx,
  271.                      int32 bestSoFar));
  272. int32    LumMotionErrorB _ANSI_ARGS_((LumBlock current, MpegFrame *prevFrame,
  273.                      int by, int bx, int my, int mx,
  274.                      int32 bestSoFar));
  275. int32    LumMotionErrorC _ANSI_ARGS_((LumBlock current, MpegFrame *prevFrame,
  276.                      int by, int bx, int my, int mx,
  277.                      int32 bestSoFar));
  278. int32    LumMotionErrorD _ANSI_ARGS_((LumBlock current, MpegFrame *prevFrame,
  279.                      int by, int bx, int my, int mx,
  280.                      int32 bestSoFar));
  281. int32    LumMotionErrorSubSampled _ANSI_ARGS_((LumBlock currentBlock, MpegFrame *prevFrame,
  282.               int by, int bx, int my, int mx,
  283.               int startY, int startX));
  284. void    ComputeSNR _ANSI_ARGS_((uint8 **origData, uint8 **newData,
  285.                 int ySize, int xSize,
  286.                 float *snr, float *psnr));
  287.  
  288.  
  289. /*==================*
  290.  * GLOBAL VARIABLES *
  291.  *==================*/
  292.  
  293. extern int pixelFullSearch;
  294. extern int searchRange;
  295. extern int qscaleI;
  296. extern int gopSize;
  297. extern int slicesPerFrame;
  298. extern int blocksPerSlice;
  299. extern FrameTable  *frameTable;
  300. extern int referenceFrame;
  301. extern int quietTime;        /* shut up for at least quietTime seconds;
  302.                  * negative means shut up forever
  303.                  */
  304.  
  305. extern boolean frameSummary;    /* TRUE = frame summaries should be printed */
  306. extern boolean    printSNR;
  307. extern boolean    decodeRefFrames;    /* TRUE = should decode I and P frames */
  308. extern int    fCode;
  309.