2 /**************************************************************************
4 * This code is developed by Adam Li. This software is an *
5 * implementation of a part of one or more MPEG-4 Video tools as *
6 * specified in ISO/IEC 14496-2 standard. Those intending to use this *
7 * software module in hardware or software products are advised that its *
8 * use may infringe existing patents or copyrights, and any such use *
9 * would be at such party's own risk. The original developer of this *
10 * software module and his/her company, and subsequent editors and their *
11 * companies (including Project Mayo), will have no liability for use of *
12 * this software or modifications or derivatives thereof. *
14 * Project Mayo gives users of the Codec a license to this software *
15 * module or modifications thereof for use in hardware or software *
16 * products claiming conformance to the MPEG-4 Video Standard as *
17 * described in the Open DivX license. *
19 * The complete Open DivX license can be found at *
20 * http://www.projectmayo.com/opendivx/license.php . *
22 **************************************************************************/
24 /**************************************************************************
28 * Copyright (C) 2001 Project Mayo
33 * DivX Advance Research Center <darc@projectmayo.com>
35 **************************************************************************/
37 /* This file contains some functions for text coding of MacroBlocks. */
38 /* Some codes of this project come from MoMuSys MPEG-4 implementation. */
39 /* Please see seperate acknowledgement file for a list of contributors. */
41 #include "text_code.h"
46 Void
BlockPredict (SInt
*curr
, /*SInt *rec_curr,*/
47 Int x_pos
, Int y_pos
, UInt width
, Int fblock
[][8]);
48 Void
BlockRebuild (SInt
*rec_curr
, SInt
*comp
, Int pred_type
, Int max
,
49 Int x_pos
, Int y_pos
, UInt width
, UInt edge
, Int fblock
[][8]);
50 Void
BlockQuantH263 (Int
*coeff
, Int QP
, Int mode
, Int type
,
51 Int
*qcoeff
, Int maxDC
, Int image_type
);
52 Void
BlockDequantH263 (Int
*qcoeff
, Int QP
, Int mode
, Int type
,
53 Int
*rcoeff
, Int image_type
, Int short_video_header
, Int bits_per_pixel
);
56 /***********************************************************CommentBegin******
58 * -- CodeMB -- Code, decode and reconstruct Macroblock
59 * combined with substraction and addition operation
62 * Int x_pos x_position of Macroblock
63 * Int y_pos y_position of Macroblock
64 * UInt width width of Vop bounding box (unpadded size)
65 * Int QP Quantization parameter
66 * Int Mode Macroblock coding mode
69 * Vop *curr current Vop, uncoded
70 * Vop *rec_curr current Vop, decoded and reconstructed
71 * Vop *comp current Vop, motion compensated
72 * Int *qcoeff coefficient block (384 * sizeof(Int))
74 ***********************************************************CommentEnd********/
76 Void
CodeMB(Vop
*curr
, Vop
*rec_curr
, Vop
*comp
, Int x_pos
, Int y_pos
, UInt width
,
77 Int QP
, Int Mode
, Int
*qcoeff
)
86 SInt
*current
, *recon
, *compensated
= NULL
;
91 Int type
; /* luma = 1, chroma = 2 */
96 int operation
= curr
->prediction_type
;
97 /* This variable is for combined operation.
98 If it is an I_VOP, then MB in curr is reconstruct into rec_curr,
99 and comp is not used at all (i.e., it can be set to NULL).
100 If it is a P_VOP, then MB in curr is reconstructed, and the result
101 added with MB_comp is written into rec_curr.
102 - adamli 11/19/2000 */
104 Int max
= GetVopBrightWhite(curr
);
105 /* This variable is the max value for the clipping of the reconstructed image. */
111 for (k
= 0; k
< 6; k
++)
119 current
= (SInt
*) GetImageData (GetVopY (curr
));
125 current
= (SInt
*) GetImageData (GetVopY (curr
));
131 current
= (SInt
*) GetImageData (GetVopY (curr
));
137 current
= (SInt
*) GetImageData (GetVopY (curr
));
143 current
= (SInt
*) GetImageData (GetVopU (curr
));
149 current
= (SInt
*) GetImageData (GetVopV (curr
));
154 BlockPredict (current
, x
, y
, xwidth
, fblock
[k
]);
157 for (k
= 0; k
< 6; k
++)
160 for (i
= 0; i
< 8; i
++)
161 for (j
= 0; j
< 8; j
++)
162 tmp
[s
++] = (SInt
) fblock
[k
][i
][j
];
168 for (s
= 0; s
< 64; s
++)
169 coeff_ind
[s
] = (Int
) tmp
[s
];
174 /* For this release, only H263 quantization is supported. - adamli */
175 BlockQuantH263(coeff_ind
,QP
,Mode
,type
,qcoeff_ind
,
176 GetVopBrightWhite(curr
),1);
177 BlockDequantH263(qcoeff_ind
,QP
,Mode
,type
,rcoeff_ind
,1, 0, GetVopBitsPerPixel(curr
));
179 for (s
= 0; s
< 64; s
++)
180 tmp
[s
] = (SInt
) rcoeff_ind
[s
];
187 for (i
= 0; i
< 8; i
++)
188 for (j
= 0; j
< 8; j
++)
189 iblock
[k
][i
][j
] = (Int
)tmp
[s
++];
195 if (Mode
== MODE_INTRA
||Mode
==MODE_INTRA_Q
)
196 for (i
= 0; i
< 8; i
++)
197 for (j
= 0; j
< 8; j
++)
198 iblock
[k
][i
][j
] = MIN (GetVopBrightWhite(curr
), MAX (0, iblock
[k
][i
][j
]));
208 recon
= (SInt
*) GetImageData (GetVopY (rec_curr
));
209 if (operation
== P_VOP
) compensated
= (SInt
*) GetImageData (GetVopY (comp
));
210 BlockRebuild (recon
, compensated
, operation
, max
, x_pos
, y_pos
, width
, 16, iblock
[0]);
211 BlockRebuild (recon
, compensated
, operation
, max
, x_pos
+ 8, y_pos
, width
, 16, iblock
[1]);
212 BlockRebuild (recon
, compensated
, operation
, max
, x_pos
, y_pos
+ 8, width
, 16, iblock
[2]);
213 BlockRebuild (recon
, compensated
, operation
, max
, x_pos
+ 8, y_pos
+ 8, width
, 16, iblock
[3]);
217 recon
= (SInt
*) GetImageData (GetVopU (rec_curr
));
218 if (operation
== P_VOP
) compensated
= (SInt
*) GetImageData (GetVopU (comp
));
219 BlockRebuild (recon
, compensated
, operation
, max
,
220 x_pos
/2, y_pos
/2, width
/2, 8, iblock
[4]);
224 recon
= (SInt
*) GetImageData (GetVopV (rec_curr
));
225 if (operation
== P_VOP
) compensated
= (SInt
*) GetImageData (GetVopV (comp
));
226 BlockRebuild (recon
, compensated
, operation
, max
,
227 x_pos
/2, y_pos
/2, width
/2, 8, iblock
[5]);
236 /***********************************************************CommentBegin******
238 * -- BlockPredict -- Get prediction for an Intra block
241 * Get prediction for an Intra block
244 * Int x_pos x_position of Macroblock
245 * Int y_pos y_position of Macroblock
246 * UInt width width of Vop bounding box
249 * SInt *curr current uncoded Vop data
250 * SInt *rec_curr reconstructed Vop data area
253 * Int fblock[][8] the prediction block to be coded for bitstream
255 ***********************************************************CommentEnd********/
257 BlockPredict (SInt
*curr
, /*SInt *rec_curr,*/ Int x_pos
, Int y_pos
,
258 UInt width
, Int fblock
[][8])
262 for (i
= 0; i
< 8; i
++)
264 for (j
= 0; j
< 8; j
++)
266 fblock
[i
][j
] = curr
[(y_pos
+i
)*width
+ x_pos
+j
];
272 /***********************************************************CommentBegin******
274 * -- BlockRebuild -- Reconstructs a block into data area of Vop
277 * Reconstructs a block into data area of Vop
280 * Int x_pos x_position of Macroblock
281 * Int y_pos y_position of Macroblock
282 * UInt width width of Vop bounding box
285 * SInt *rec_curr current Vop data area to be reconstructed
288 * Does reconstruction for Intra predicted blocks also
290 ***********************************************************CommentEnd********/
293 BlockRebuild (SInt
*rec_curr
, SInt
*comp
, Int pred_type
, Int max
,
294 Int x_pos
, Int y_pos
, UInt width
, UInt edge
, Int fblock
[][8])
296 /* this function now does rebuild and generating error at the same time */
301 padded_width
= width
+ 2 * edge
;
302 rec
= rec_curr
+ edge
* padded_width
+ edge
;
304 if (pred_type
== I_VOP
)
307 p
= rec
+ y_pos
* padded_width
+ x_pos
;
309 for (i
= 0; i
< 8; i
++)
311 for (j
= 0; j
< 8; j
++)
313 SInt temp
= fblock
[i
][j
];
314 *(p
++) = CLIP(temp
, 0, max
);
317 p
+= padded_width
- 8;
320 else if (pred_type
== P_VOP
)
323 p
= rec
+ y_pos
* padded_width
+ x_pos
;
324 pc
= comp
+ y_pos
* width
+ x_pos
;
326 for (i
= 0; i
< 8; i
++)
328 for (j
= 0; j
< 8; j
++)
330 SInt temp
= *(pc
++) + fblock
[i
][j
];
331 *(p
++) = CLIP(temp
, 0, max
);
334 p
+= padded_width
- 8;
342 /***********************************************************CommentBegin******
344 * -- BlockQuantH263 -- 8x8 block level quantization
347 * 8x8 block level quantization
350 * Int *coeff non-quantized coefficients
351 * Int QP quantization parameter
352 * Int Mode Macroblock coding mode
355 * Int *qcoeff quantized coefficients
357 ***********************************************************CommentEnd********/
359 BlockQuantH263 (Int
*coeff
,
378 //if(QP != 5) printf("BlockQuantH263 %d\n", QP);
379 if (!(QP
> 0 && (QP
< 32*image_type
))) return;
380 if (!(type
== 1 || type
== 2)) return;
382 if (mode
== MODE_INTRA
|| mode
== MODE_INTRA_Q
)
384 dc_scaler
= cal_dc_scaler(QP
,type
);
385 qcoeff
[0] = MAX(1,MIN(maxDC
-1, (coeff
[0] + dc_scaler
/2)/dc_scaler
));
388 for (i
= 1; i
< 64; i
++)
390 level
= (abs(coeff
[i
])) / step
;
391 result
= (coeff
[i
] >= 0) ? level
: -level
;
392 qcoeff
[i
] = MIN(2047, MAX(-2048, result
));
399 for (i
= 0; i
< 64; i
++)
401 level
= (abs(coeff
[i
]) - offset
) / step
;
402 result
= (coeff
[i
] >= 0) ? level
: -level
;
403 qcoeff
[i
] = MIN(2047, MAX(-2048, result
));
411 /***********************************************************CommentBegin******
413 * -- BlockDequantH263 -- 8x8 block dequantization
416 * 8x8 block dequantization
419 * Int *qcoeff quantized coefficients
420 * Int QP quantization parameter
421 * Int mode Macroblock coding mode
422 * Int short_video_header Flag to signal short video header bitstreams (H.263)
425 * Int *rcoeff reconstructed (dequantized) coefficients
427 ***********************************************************CommentEnd********/
429 BlockDequantH263 (Int
*qcoeff
, Int QP
, Int mode
, Int type
, Int
*rcoeff
,
430 Int image_type
, Int short_video_header
, Int bits_per_pixel
)
436 lim
= (1 << (bits_per_pixel
+ 3));
440 for (i
= 0; i
< 64; i
++)
444 /* 16.11.98 Sven Brandau: "correct saturation" due to N2470, Clause 2.1.6 */
445 qcoeff
[i
] = MIN(2047, MAX(-2048, qcoeff
[i
] ));
447 rcoeff
[i
] = QP
* (2*ABS(qcoeff
[i
]) + 1);
449 rcoeff
[i
] = QP
* (2*ABS(qcoeff
[i
]) + 1) - 1;
450 rcoeff
[i
] = SIGN(qcoeff
[i
]) * rcoeff
[i
];
455 if (mode
== MODE_INTRA
|| mode
== MODE_INTRA_Q
)
458 MOMCHECK(QP
> 0 && (QP
< 32*image_type
));
459 MOMCHECK(type
== 1 || type
== 2);
461 if (short_video_header
)
464 dc_scaler
= cal_dc_scaler(QP
,type
);
466 rcoeff
[0] = qcoeff
[0] * dc_scaler
;
471 /* No quantizing at all */
472 for (i
= 0; i
< 64; i
++)
474 rcoeff
[i
] = qcoeff
[i
];
477 if (mode
== MODE_INTRA
|| mode
== MODE_INTRA_Q
)
479 rcoeff
[0] = qcoeff
[0]*8;
483 if (rcoeff
[i
]>(lim
-1)) rcoeff
[i
]=(lim
-1);
484 else if (rcoeff
[i
]<(-lim
)) rcoeff
[i
]=(-lim
);