ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/freemol/trunk/src/mpeg_encode/src/frames.h
Revision: 22
Committed: Mon Jul 7 22:16:37 2008 UTC (11 years, 4 months ago) by wdelano
File size: 14081 byte(s)
Log Message:
initial checkin of mpeg_encode source
Line File contents
1 /*===========================================================================*
2 * frames.h *
3 * *
4 * stuff dealing with frames *
5 * *
6 *===========================================================================*/
7
8 /*
9 * Copyright (c) 1995 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/project/mpeg/mpeg_dist/mpeg_encode/headers/RCS/frames.h,v 1.13 1995/08/15 23:43:04 smoot Exp $
31 * $Log: frames.h,v $
32 * Revision 1.13 1995/08/15 23:43:04 smoot
33 * *** empty log message ***
34 *
35 * Revision 1.12 1995/04/14 23:13:18 smoot
36 * Reorganized for better rate control. Added overflow in DCT values
37 * handling.
38 *
39 * Revision 1.11 1995/01/19 23:54:46 smoot
40 * allow computediffdcts to un-assert parts of the pattern
41 *
42 * Revision 1.10 1995/01/16 07:43:10 eyhung
43 * Added realQuiet
44 *
45 * Revision 1.9 1995/01/10 23:15:28 smoot
46 * Fixed searchRange lack of def
47 *
48 * Revision 1.8 1994/11/15 00:55:36 smoot
49 * added printMSE
50 *
51 * Revision 1.7 1994/11/14 22:51:02 smoot
52 * added specifics flag. Added BlockComputeSNR parameters
53 *
54 * Revision 1.6 1994/11/01 05:07:23 darryl
55 * with rate control changes added
56 *
57 * Revision 1.1 1994/09/27 01:02:55 darryl
58 * Initial revision
59 *
60 * Revision 1.5 1993/07/22 22:24:23 keving
61 * nothing
62 *
63 * Revision 1.4 1993/07/09 00:17:23 keving
64 * nothing
65 *
66 * Revision 1.3 1993/06/03 21:08:53 keving
67 * nothing
68 *
69 * Revision 1.2 1993/03/02 19:00:27 keving
70 * nothing
71 *
72 * Revision 1.1 1993/02/19 20:15:51 keving
73 * nothing
74 *
75 */
76
77
78 #ifndef FRAMES_INCLUDED
79 #define FRAMES_INCLUDED
80
81 /*==============*
82 * HEADER FILES *
83 *==============*/
84
85 #include "ansi.h"
86 #include "mtypes.h"
87 #include "mheaders.h"
88 #include "frame.h"
89
90
91 /*===========*
92 * CONSTANTS *
93 *===========*/
94
95 #define I_FRAME 1
96 #define P_FRAME 2
97 #define B_FRAME 3
98
99 #define LUM_BLOCK 0
100 #define CHROM_BLOCK 1
101 #define CR_BLOCK 2
102 #define CB_BLOCK 3
103
104 #define MOTION_FORWARD 0
105 #define MOTION_BACKWARD 1
106 #define MOTION_INTERPOLATE 2
107
108
109 #define USE_HALF 0
110 #define USE_FULL 1
111
112 /* motion vector stuff */
113 #define FORW_F_CODE fCode /* from picture header */
114 #define BACK_F_CODE fCode
115 #define FORW_F (1 << (FORW_F_CODE - 1))
116 #define BACK_F (1 << (BACK_F_CODE - 1))
117 #define RANGE_NEG (-(1 << (3 + FORW_F_CODE)))
118 #define RANGE_POS ((1 << (3 + FORW_F_CODE))-1)
119 #define MODULUS (1 << (4 + FORW_F_CODE))
120
121 #define ORIGINAL_FRAME 0
122 #define DECODED_FRAME 1
123
124
125 /*=======================*
126 * STRUCTURE DEFINITIONS *
127 *=======================*/
128
129 typedef struct FrameTableStruct {
130 /* the following are all initted once and never changed */
131 /* (they depend only on the pattern */
132 char typ;
133 struct FrameTableStruct *next;
134 struct FrameTableStruct *prev;
135
136 /* nextOutput is a pointer to next frame table entry to output */
137 struct FrameTableStruct *nextOutput;
138
139 boolean freeNow; /* TRUE iff no frames point back to this */
140
141 int number;
142
143 int bFrameNumber; /* actual frame number, if a b-frame */
144
145 } FrameTable;
146
147
148 /*==================*
149 * TYPE DEFINITIONS *
150 *==================*/
151
152 typedef struct dct_data_tye_struct {
153 char useMotion;
154 char pattern, mode;
155 int fmotionX, fmotionY, bmotionX, bmotionY;
156 } dct_data_type;
157
158 void EncodeYDC _ANSI_ARGS_((int32 dc_term, int32 *pred_term, BitBucket *bb));
159 void EncodeCDC _ANSI_ARGS_((int32 dc_term, int32 *pred_term, BitBucket *bb));
160
161
162 /*========*
163 * MACROS *
164 *========*/
165
166 #define FRAME_TYPE(num) framePattern[num % framePatternLen]
167
168 /* return ceiling(a/b) where a, b are ints, using temp value c */
169 #define int_ceil_div(a,b,c) ((b*(c = a/b) < a) ? (c+1) : c)
170 #define int_floor_div(a,b,c) ((b*(c = a/b) > a) ? (c-1) : c)
171
172 /* assumes many things:
173 * block indices are (y,x)
174 * variables y_dc_pred, cr_dc_pred, and cb_dc_pred
175 * flat block fb exists
176 */
177 #define GEN_I_BLOCK(frameType, frame, bb, mbAI, qscale) { \
178 boolean overflow, overflowChange=FALSE; \
179 int overflowValue = 0; \
180 do { \
181 overflow = Mpost_QuantZigBlock(dct[y][x], fb[0], \
182 qscale, TRUE)==MPOST_OVERFLOW; \
183 overflow |= Mpost_QuantZigBlock(dct[y][x+1], fb[1], \
184 qscale, TRUE)==MPOST_OVERFLOW; \
185 overflow |= Mpost_QuantZigBlock(dct[y+1][x], fb[2], \
186 qscale, TRUE)==MPOST_OVERFLOW; \
187 overflow |= Mpost_QuantZigBlock(dct[y+1][x+1], fb[3], \
188 qscale, TRUE)==MPOST_OVERFLOW; \
189 overflow |= Mpost_QuantZigBlock(dctb[y >> 1][x >> 1], \
190 fb[4], qscale, TRUE)==MPOST_OVERFLOW; \
191 overflow |= Mpost_QuantZigBlock(dctr[y >> 1][x >> 1], \
192 fb[5], qscale, TRUE)==MPOST_OVERFLOW; \
193 if ((overflow) && (qscale!=31)) { \
194 overflowChange = TRUE; overflowValue++; \
195 qscale++; \
196 } else overflow = FALSE; \
197 } while (overflow); \
198 Mhead_GenMBHeader(bb, \
199 frameType /* pict_code_type */, mbAI /* addr_incr */, \
200 qscale /* q_scale */, \
201 0 /* forw_f_code */, 0 /* back_f_code */, \
202 0 /* horiz_forw_r */, 0 /* vert_forw_r */, \
203 0 /* horiz_back_r */, 0 /* vert_back_r */, \
204 0 /* motion_forw */, 0 /* m_horiz_forw */, \
205 0 /* m_vert_forw */, 0 /* motion_back */, \
206 0 /* m_horiz_back */, 0 /* m_vert_back */, \
207 0 /* mb_pattern */, TRUE /* mb_intra */); \
208 \
209 /* Y blocks */ \
210 EncodeYDC(fb[0][0], &y_dc_pred, bb); \
211 Mpost_RLEHuffIBlock(fb[0], bb); \
212 EncodeYDC(fb[1][0], &y_dc_pred, bb); \
213 Mpost_RLEHuffIBlock(fb[1], bb); \
214 EncodeYDC(fb[2][0], &y_dc_pred, bb); \
215 Mpost_RLEHuffIBlock(fb[2], bb); \
216 EncodeYDC(fb[3][0], &y_dc_pred, bb); \
217 Mpost_RLEHuffIBlock(fb[3], bb); \
218 \
219 /* CB block */ \
220 EncodeCDC(fb[4][0], &cb_dc_pred, bb); \
221 Mpost_RLEHuffIBlock(fb[4], bb); \
222 \
223 /* CR block */ \
224 EncodeCDC(fb[5][0], &cr_dc_pred, bb); \
225 Mpost_RLEHuffIBlock(fb[5], bb); \
226 if (overflowChange) qscale -= overflowValue; \
227 }
228
229 #define BLOCK_TO_FRAME_COORD(bx1, bx2, x1, x2) { \
230 x1 = (bx1)*DCTSIZE; \
231 x2 = (bx2)*DCTSIZE; \
232 }
233
234 #define MOTION_TO_FRAME_COORD(bx1, bx2, mx1, mx2, x1, x2) { \
235 x1 = (bx1)*DCTSIZE+(mx1); \
236 x2 = (bx2)*DCTSIZE+(mx2); \
237 }
238
239 #define COORD_IN_FRAME(fy,fx, type) \
240 ((type == LUM_BLOCK) ? \
241 ((fy >= 0) && (fx >= 0) && (fy < Fsize_y) && (fx < Fsize_x)) : \
242 ((fy >= 0) && (fx >= 0) && (fy < (Fsize_y>>1)) && (fx < (Fsize_x>>1))))
243
244 #define ENCODE_MOTION_VECTOR(x,y,xq, yq, xr, yr, f) { \
245 int tempC; \
246 \
247 if ( x < RANGE_NEG ) tempX = x + MODULUS; \
248 else if ( x > RANGE_POS ) tempX = x - MODULUS; \
249 else tempX = x; \
250 \
251 if ( y < RANGE_NEG ) tempY = y + MODULUS; \
252 else if ( y > RANGE_POS ) tempY = y - MODULUS; \
253 else tempY = y; \
254 \
255 if ( tempX >= 0 ) { \
256 xq = int_ceil_div(tempX, f, tempC); \
257 xr = f - 1 + tempX - xq*f; \
258 } else { \
259 xq = int_floor_div(tempX, f, tempC); \
260 xr = f - 1 - tempX + xq*f; \
261 } \
262 \
263 if ( tempY >= 0 ) { \
264 yq = int_ceil_div(tempY, f, tempC); \
265 yr = f - 1 + tempY - yq*f; \
266 } else { \
267 yq = int_floor_div(tempY, f, tempC); \
268 yr = f - 1 - tempY + yq*f; \
269 } \
270 }
271
272
273 #define DoQuant(bit, src, dest) \
274 if (pattern & bit) { \
275 switch (Mpost_QuantZigBlock(src, dest, QScale, FALSE)) { \
276 case MPOST_NON_ZERO: \
277 break; \
278 case MPOST_ZERO: \
279 pattern ^= bit; \
280 break; \
281 case MPOST_OVERFLOW: \
282 if (QScale != 31) { \
283 QScale++; \
284 overflowChange = TRUE; \
285 overflowValue++; \
286 goto calc_blocks; \
287 } \
288 break; \
289 } \
290 }
291
292 /*===============================*
293 * EXTERNAL PROCEDURE prototypes *
294 *===============================*/
295
296 void ComputeBMotionLumBlock _ANSI_ARGS_((MpegFrame *prev, MpegFrame *next,
297 int by, int bx, int mode, int fmy, int fmx,
298 int bmy, int bmx, LumBlock motionBlock));
299 int BMotionSearch _ANSI_ARGS_((LumBlock currentBlock, MpegFrame *prev, MpegFrame *next,
300 int by, int bx, int *fmy, int *fmx, int *bmy, int *bmx, int oldMode));
301
302
303 void ComputeDiffDCTs _ANSI_ARGS_((MpegFrame *current, MpegFrame *prev, int by, int bx,
304 int my, int mx, int *pattern));
305 int ComputeDiffDCTBlock _ANSI_ARGS_((Block current, Block dest, Block motionBlock));
306 void ComputeMotionBlock _ANSI_ARGS_((uint8 **prev, int by, int bx, int my, int mx,
307 Block motionBlock));
308 void ComputeMotionLumBlock _ANSI_ARGS_((MpegFrame *prevFrame, int by,
309 int bx, int my, int mx,
310 LumBlock motionBlock));
311 int32 ComputeBlockMAD _ANSI_ARGS_((Block current, Block prev));
312
313 void GenIFrame _ANSI_ARGS_((BitBucket *bb, MpegFrame *mf));
314 void GenPFrame _ANSI_ARGS_((BitBucket *bb, MpegFrame *current, MpegFrame *prev));
315 void GenBFrame _ANSI_ARGS_((BitBucket *bb, MpegFrame *curr, MpegFrame *prev, MpegFrame *next));
316 void AllocDctBlocks _ANSI_ARGS_((void ));
317
318 float ShowIFrameSummary _ANSI_ARGS_((int inputFrameBits, int32 totalBits, FILE *fpointer));
319 float ShowPFrameSummary _ANSI_ARGS_((int inputFrameBits, int32 totalBits, FILE *fpointer));
320 float ShowBFrameSummary _ANSI_ARGS_((int inputFrameBits, int32 totalBits, FILE *fpointer));
321
322
323 /* DIFFERENCE FUNCTIONS */
324
325 int32 LumBlockMAD _ANSI_ARGS_((LumBlock currentBlock, LumBlock motionBlock, int32 bestSoFar));
326 int32 LumBlockMSE _ANSI_ARGS_((LumBlock currentBlock, LumBlock motionBlock, int32 bestSoFar));
327 int32 LumMotionError _ANSI_ARGS_((LumBlock currentBlock, MpegFrame *prev,
328 int by, int bx, int my, int mx,
329 int32 bestSoFar));
330 int32 LumAddMotionError _ANSI_ARGS_((LumBlock currentBlock,
331 LumBlock blockSoFar, MpegFrame *prev,
332 int by, int bx, int my, int mx,
333 int32 bestSoFar));
334 int32 LumMotionErrorA _ANSI_ARGS_((LumBlock current, MpegFrame *prevFrame,
335 int by, int bx, int my, int mx,
336 int32 bestSoFar));
337 int32 LumMotionErrorB _ANSI_ARGS_((LumBlock current, MpegFrame *prevFrame,
338 int by, int bx, int my, int mx,
339 int32 bestSoFar));
340 int32 LumMotionErrorC _ANSI_ARGS_((LumBlock current, MpegFrame *prevFrame,
341 int by, int bx, int my, int mx,
342 int32 bestSoFar));
343 int32 LumMotionErrorD _ANSI_ARGS_((LumBlock current, MpegFrame *prevFrame,
344 int by, int bx, int my, int mx,
345 int32 bestSoFar));
346 int32 LumMotionErrorSubSampled _ANSI_ARGS_((LumBlock currentBlock, MpegFrame *prevFrame,
347 int by, int bx, int my, int mx,
348 int startY, int startX));
349 void BlockComputeSNR _ANSI_ARGS_((MpegFrame *current,
350 float *snr, float *psnr));
351 int32 time_elapsed _ANSI_ARGS_((void));
352 void AllocDctBlocks _ANSI_ARGS_((void));
353
354 /*==================*
355 * GLOBAL VARIABLES *
356 *==================*/
357
358 extern int pixelFullSearch;
359 extern int searchRangeP,searchRangeB;
360 extern int qscaleI;
361 extern int gopSize;
362 extern int slicesPerFrame;
363 extern int blocksPerSlice;
364 extern int referenceFrame;
365 extern int specificsOn;
366 extern int quietTime; /* shut up for at least quietTime seconds;
367 * negative means shut up forever
368 */
369 extern boolean realQuiet; /* TRUE = no messages to stdout */
370
371 extern boolean frameSummary; /* TRUE = frame summaries should be printed */
372 extern boolean printSNR;
373 extern boolean printMSE;
374 extern boolean decodeRefFrames; /* TRUE = should decode I and P frames */
375 extern int fCodeI,fCodeP,fCodeB;
376 extern boolean forceEncodeLast;
377 extern int TIME_RATE;
378
379 #endif /* FRAMES_INCLUDED */