1
/*************************************************************************
3
This software module was originally developed by
5
Ming-Chieh Lee (mingcl@microsoft.com), Microsoft Corporation
6
Wei-ge Chen (wchen@microsoft.com), Microsoft Corporation
7
Bruce Lin (blin@microsoft.com), Microsoft Corporation
8
Chuang Gu (chuanggu@microsoft.com), Microsoft Corporation
9
Simon Winder (swinder@microsoft.com), Microsoft Corporation
12
Wei Wu (weiwu@stallion.risc.rockwell.com), Rockwell Science Center
14
in the course of development of the MPEG-4 Video (ISO/IEC 14496-2).
15
This software module is an implementation of a part of one or more MPEG-4 Video tools
16
as specified by the MPEG-4 Video.
17
ISO/IEC gives users of the MPEG-4 Video free license to this software module or modifications
18
thereof for use in hardware or software products claiming conformance to the MPEG-4 Video.
19
Those intending to use this software module in hardware or software products are advised that its use may infringe existing patents.
20
The original developer of this software module and his/her company,
21
the subsequent editors and their companies,
22
and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation.
23
Copyright is not released for non MPEG-4 Video conforming products.
24
Microsoft retains full right to use the code for his/her own purpose,
25
assign or donate the code to a third party and to inhibit third parties from using the code for non <MPEG standard> conforming products.
26
This copyright notice must be included in all copies or derivative works.
28
Copyright (c) 1996, 1997.
39
May. 9 1998: add boundary by Hyundai Electronics
40
Cheol-Soo Park (cspark@super5.hyundai.co.kr)
41
*************************************************************************/
52
#include "bitstrm.hpp"
53
#include "entropy.hpp"
54
#include "huffman.hpp"
61
static char BASED_CODE THIS_FILE[] = __FILE__;
67
Int divroundnearest(Int i, Int iDenom)
71
return (i+(iDenom>>1))/iDenom;
73
return (i-(iDenom>>1))/iDenom;
76
Void CVideoObject::inverseQuantizeIntraDc (Int* rgiCoefQ, Int iDcScaler)
79
m_rgiDCTcoef [0] = (Float) rgiCoefQ [0] * 8;
81
m_rgiDCTcoef [0] = rgiCoefQ [0] * iDcScaler;
84
m_rgiDCTcoef [0] = rgiCoefQ [0] * 8;
85
else if (iQP >= 5 && iQP <= 8)
86
m_rgiDCTcoef [0] = rgiCoefQ [0] * 2 * iQP;
87
else if (iQP >= 9 && iQP <= 24)
88
m_rgiDCTcoef [0] = rgiCoefQ [0] * (iQP + 8);
90
m_rgiDCTcoef [0] = rgiCoefQ [0] * (iQP * 2 - 16);
95
Void CVideoObject::inverseQuantizeDCTcoefH263 (Int* rgiCoefQ, Int iStart, Int iQP)
98
for (i = iStart; i < BLOCK_SQUARE_SIZE; i++) {
100
if (iQP % 2 == 1) //?
101
m_rgiDCTcoef [i] = iQP * (2 * abs (rgiCoefQ[i]) + 1);
103
m_rgiDCTcoef [i] = iQP * (2 * abs (rgiCoefQ[i]) + 1) - 1;
104
m_rgiDCTcoef [i] = sign (rgiCoefQ[i]) * m_rgiDCTcoef [i] ;
107
m_rgiDCTcoef [i] = 0;
111
Void CVideoObject::inverseQuantizeIntraDCTcoefMPEG (Int* rgiCoefQ, Int iStart, Int iQP,
112
Bool bUseAlphaMatrix, Int iAuxComp)
115
Int iSum = m_rgiDCTcoef [0];
116
Bool bCoefQAllZero = (m_rgiDCTcoef [0] == 0)? TRUE : FALSE;
117
Int *piQuantizerMatrix;
119
piQuantizerMatrix = m_volmd.rgiIntraQuantizerMatrixAlpha[iAuxComp];
121
piQuantizerMatrix = m_volmd.rgiIntraQuantizerMatrix;
123
Int iMaxVal = 1<<(m_volmd.nBits+3); // NBIT
125
for (i = iStart; i < BLOCK_SQUARE_SIZE; i++) {
126
if (rgiCoefQ [i] == 0)
127
m_rgiDCTcoef [i] = 0;
129
m_rgiDCTcoef [i] = iQP * rgiCoefQ [i] * piQuantizerMatrix [i] / 8;
131
m_rgiDCTcoef [i] = checkrange (m_rgiDCTcoef [i], -2048, 2047);
133
m_rgiDCTcoef [i] = checkrange (m_rgiDCTcoef [i], -iMaxVal, iMaxVal-1);
134
bCoefQAllZero = FALSE;
136
iSum ^= m_rgiDCTcoef [i];
138
if (!bCoefQAllZero) {
139
if ((iSum & 0x00000001) == 0)
140
m_rgiDCTcoef [i - 1] ^= 0x00000001;
144
Void CVideoObject::inverseQuantizeInterDCTcoefMPEG (Int* rgiCoefQ, Int iStart, Int iQP,
145
Bool bUseAlphaMatrix, Int iAuxComp)
149
Bool bCoefQAllZero = TRUE;
150
Int *piQuantizerMatrix;
152
piQuantizerMatrix = m_volmd.rgiInterQuantizerMatrixAlpha[iAuxComp];
154
piQuantizerMatrix = m_volmd.rgiInterQuantizerMatrix;
156
Int iMaxVal = 1<<(m_volmd.nBits+3); // NBIT
158
for (i = iStart; i < BLOCK_SQUARE_SIZE; i++) {
159
if (rgiCoefQ [i] == 0)
160
m_rgiDCTcoef [i] = 0;
162
m_rgiDCTcoef [i] = (iQP * (rgiCoefQ [i] * 2 + sign(rgiCoefQ [i])) * piQuantizerMatrix [i]) / 16;
164
m_rgiDCTcoef [i] = checkrange (m_rgiDCTcoef [i], -2048, 2047);
166
m_rgiDCTcoef [i] = checkrange (m_rgiDCTcoef [i], -iMaxVal, iMaxVal-1);
167
bCoefQAllZero = FALSE;
169
iSum ^= m_rgiDCTcoef [i];
171
if (!bCoefQAllZero) {
172
if ((iSum & 0x00000001) == 0)
173
m_rgiDCTcoef [i - 1] ^= 0x00000001;
177
const BlockMemory CVideoObject::findPredictorBlock (
179
IntraPredDirection predDir,
180
const MacroBlockMemory* pmbmLeft,
181
const MacroBlockMemory* pmbmTop,
182
const MacroBlockMemory* pmbmLeftTop,
183
const MacroBlockMemory* pmbmCurr,
184
const CMBMode* pmbmdLeft,
185
const CMBMode* pmbmdTop,
186
const CMBMode* pmbmdLeftTop,
187
const CMBMode* pmbmdCurr,
191
const BlockMemory blkmRet = NULL;
193
Int iBlk, iAuxComp = 0;
197
iAuxComp = (iBlkOrig-7)/4;
198
iBlk = ((iBlkOrig-7)&3)+7;
202
/*BBM// Added for Boundary by Hyundai(1998-5-9)
203
if (m_vopmd.bInterlace && pmbmdCurr->m_bMerged [0])
204
swapTransparentModes ((CMBMode*)pmbmdCurr, BBM);
205
// End of Hyundai(1998-5-9)*/
206
if (predDir == HORIZONTAL) {
209
if (pmbmLeft != NULL &&
210
(pmbmdLeft->m_dctMd == INTRA || pmbmdLeft->m_dctMd == INTRAQ) &&
211
pmbmdLeft->m_rgTranspStatus [Y_BLOCK2] != ALL) {
212
blkmRet = pmbmLeft->rgblkm [Y_BLOCK2 - 1];
213
iQPpred = pmbmdLeft->m_stepSize;
217
if (pmbmdCurr->m_rgTranspStatus [Y_BLOCK1] != ALL) {
218
blkmRet = pmbmCurr->rgblkm [Y_BLOCK1 - 1];
219
iQPpred = pmbmdCurr->m_stepSize;
223
if (pmbmLeft != NULL &&
224
(pmbmdLeft->m_dctMd == INTRA || pmbmdLeft->m_dctMd == INTRAQ) &&
225
pmbmdLeft->m_rgTranspStatus [Y_BLOCK4] != ALL) {
226
blkmRet = pmbmLeft->rgblkm [Y_BLOCK4 - 1];
227
iQPpred = pmbmdLeft->m_stepSize;
231
if (pmbmdCurr->m_rgTranspStatus [Y_BLOCK3] != ALL) {
232
blkmRet = pmbmCurr->rgblkm [Y_BLOCK3 - 1];
233
iQPpred = pmbmdCurr->m_stepSize;
237
if (pmbmLeft != NULL &&
238
(pmbmdLeft->m_dctMd == INTRA || pmbmdLeft->m_dctMd == INTRAQ) &&
239
pmbmdLeft->m_rgTranspStatus [Y_BLOCK2] != ALL) {
240
blkmRet = pmbmLeft->rgblkm [A_BLOCK2 + iAuxComp*4 - 1];
241
iQPpred = pmbmdLeft->m_stepSizeAlpha;
245
if (pmbmdCurr->m_rgTranspStatus [Y_BLOCK1] != ALL) {
246
blkmRet = pmbmCurr->rgblkm [A_BLOCK1 + iAuxComp*4 - 1];
247
iQPpred = pmbmdCurr->m_stepSizeAlpha;
251
if (pmbmLeft != NULL &&
252
(pmbmdLeft->m_dctMd == INTRA || pmbmdLeft->m_dctMd == INTRAQ) &&
253
pmbmdLeft->m_rgTranspStatus [Y_BLOCK4] != ALL) {
254
blkmRet = pmbmLeft->rgblkm [A_BLOCK4 + iAuxComp*4 - 1];
255
iQPpred = pmbmdLeft->m_stepSizeAlpha;
259
if (pmbmdCurr->m_rgTranspStatus [Y_BLOCK3] != ALL) {
260
blkmRet = pmbmCurr->rgblkm [A_BLOCK3 + iAuxComp*4 - 1];
261
iQPpred = pmbmdCurr->m_stepSizeAlpha;
264
default: //U, V block
265
if (pmbmLeft != NULL &&
266
(pmbmdLeft->m_dctMd == INTRA || pmbmdLeft->m_dctMd == INTRAQ) &&
267
pmbmdLeft->m_rgTranspStatus [ALL_Y_BLOCKS] != ALL) {
268
blkmRet = pmbmLeft->rgblkm [iBlk - 1];
269
iQPpred = pmbmdLeft->m_stepSize;
273
else if (predDir == VERTICAL) {
276
if (pmbmTop != NULL &&
277
(pmbmdTop->m_dctMd == INTRA || pmbmdTop->m_dctMd == INTRAQ) &&
278
pmbmdTop->m_rgTranspStatus [Y_BLOCK3] != ALL) {
279
blkmRet = pmbmTop->rgblkm [Y_BLOCK3 - 1];
280
iQPpred = pmbmdTop->m_stepSize;
284
if (pmbmTop != NULL &&
285
(pmbmdTop->m_dctMd == INTRA || pmbmdTop->m_dctMd == INTRAQ) &&
286
pmbmdTop->m_rgTranspStatus [Y_BLOCK4] != ALL) {
287
blkmRet = pmbmTop->rgblkm [Y_BLOCK4 - 1];
288
iQPpred = pmbmdTop->m_stepSize;
292
if (pmbmdCurr->m_rgTranspStatus [Y_BLOCK1] != ALL) {
293
blkmRet = pmbmCurr->rgblkm [Y_BLOCK1 - 1];
294
iQPpred = pmbmdCurr->m_stepSize;
298
if (pmbmdCurr->m_rgTranspStatus [Y_BLOCK2] != ALL) {
299
blkmRet = pmbmCurr->rgblkm [Y_BLOCK2 - 1];
300
iQPpred = pmbmdCurr->m_stepSize;
304
if (pmbmTop != NULL &&
305
(pmbmdTop->m_dctMd == INTRA || pmbmdTop->m_dctMd == INTRAQ) &&
306
pmbmdTop->m_rgTranspStatus [Y_BLOCK3] != ALL) {
307
blkmRet = pmbmTop->rgblkm [A_BLOCK3 + iAuxComp*4 - 1];
308
iQPpred = pmbmdTop->m_stepSizeAlpha;
312
if (pmbmTop != NULL &&
313
(pmbmdTop->m_dctMd == INTRA || pmbmdTop->m_dctMd == INTRAQ) &&
314
pmbmdTop->m_rgTranspStatus [Y_BLOCK4] != ALL) {
315
blkmRet = pmbmTop->rgblkm [A_BLOCK4 + iAuxComp*4 - 1];
316
iQPpred = pmbmdTop->m_stepSizeAlpha;
320
if (pmbmdCurr->m_rgTranspStatus [Y_BLOCK1] != ALL) {
321
blkmRet = pmbmCurr->rgblkm [A_BLOCK1 + iAuxComp*4 - 1];
322
iQPpred = pmbmdCurr->m_stepSizeAlpha;
326
if (pmbmdCurr->m_rgTranspStatus [Y_BLOCK2] != ALL) {
327
blkmRet = pmbmCurr->rgblkm [A_BLOCK2 + iAuxComp*4 - 1];
328
iQPpred = pmbmdCurr->m_stepSizeAlpha;
331
default: //U, V block
332
if (pmbmTop != NULL &&
333
(pmbmdTop->m_dctMd == INTRA || pmbmdTop->m_dctMd == INTRAQ) &&
334
pmbmdTop->m_rgTranspStatus [ALL_Y_BLOCKS] != ALL) {
335
blkmRet = pmbmTop->rgblkm [iBlk - 1];
336
iQPpred = pmbmdTop->m_stepSize;
340
else if (predDir == DIAGONAL) {
343
if (pmbmLeftTop != NULL &&
344
(pmbmdLeftTop->m_dctMd == INTRA || pmbmdLeftTop->m_dctMd == INTRAQ) &&
345
pmbmdLeftTop->m_rgTranspStatus [Y_BLOCK4] != ALL) {
346
blkmRet = pmbmLeftTop->rgblkm [Y_BLOCK4 - 1];
347
iQPpred = pmbmdLeftTop->m_stepSize;
351
if (pmbmTop != NULL &&
352
(pmbmdTop->m_dctMd == INTRA || pmbmdTop->m_dctMd == INTRAQ) &&
353
pmbmdTop->m_rgTranspStatus [Y_BLOCK3] != ALL) {
354
blkmRet = pmbmTop->rgblkm [Y_BLOCK3 - 1];
355
iQPpred = pmbmdTop->m_stepSize;
359
if (pmbmLeft != NULL &&
360
(pmbmdLeft->m_dctMd == INTRA || pmbmdLeft->m_dctMd == INTRAQ) &&
361
pmbmdLeft->m_rgTranspStatus [Y_BLOCK2] != ALL) {
362
blkmRet = pmbmLeft->rgblkm [Y_BLOCK2 - 1];
363
iQPpred = pmbmdLeft->m_stepSize;
367
if (pmbmdCurr->m_rgTranspStatus [Y_BLOCK1] != ALL) {
368
blkmRet = pmbmCurr->rgblkm [Y_BLOCK1 - 1];
369
iQPpred = pmbmdCurr->m_stepSize;
373
if (pmbmLeftTop != NULL &&
374
(pmbmdLeftTop->m_dctMd == INTRA || pmbmdLeftTop->m_dctMd == INTRAQ) &&
375
pmbmdLeftTop->m_rgTranspStatus [Y_BLOCK4] != ALL) {
376
blkmRet = pmbmLeftTop->rgblkm [A_BLOCK4 + iAuxComp*4 - 1];
377
iQPpred = pmbmdLeftTop->m_stepSizeAlpha;
381
if (pmbmTop != NULL &&
382
(pmbmdTop->m_dctMd == INTRA || pmbmdTop->m_dctMd == INTRAQ) &&
383
pmbmdTop->m_rgTranspStatus [Y_BLOCK3] != ALL) {
384
blkmRet = pmbmTop->rgblkm [A_BLOCK3 + iAuxComp*4 - 1];
385
iQPpred = pmbmdTop->m_stepSizeAlpha;
389
if (pmbmLeft != NULL &&
390
(pmbmdLeft->m_dctMd == INTRA || pmbmdLeft->m_dctMd == INTRAQ) &&
391
pmbmdLeft->m_rgTranspStatus [Y_BLOCK2] != ALL) {
392
blkmRet = pmbmLeft->rgblkm [A_BLOCK2 + iAuxComp*4 - 1];
393
iQPpred = pmbmdLeft->m_stepSizeAlpha;
397
if (pmbmdCurr->m_rgTranspStatus [Y_BLOCK1] != ALL) {
398
blkmRet = pmbmCurr->rgblkm [A_BLOCK1 + iAuxComp*4 - 1];
399
iQPpred = pmbmdCurr->m_stepSizeAlpha;
402
default: //U, V block
403
if (pmbmLeftTop != NULL &&
404
(pmbmdLeftTop->m_dctMd == INTRA || pmbmdLeftTop->m_dctMd == INTRAQ) &&
405
pmbmdLeftTop->m_rgTranspStatus [ALL_Y_BLOCKS] != ALL) {
406
blkmRet = pmbmLeftTop->rgblkm [iBlk - 1];
407
iQPpred = pmbmdLeftTop->m_stepSize;
413
/*BBM// Added for Boundary by Hyundai(1998-5-9)
414
if (m_vopmd.bInterlace && pmbmdCurr->m_bMerged [0])
415
swapTransparentModes ((CMBMode*)pmbmdCurr, BBS);
416
// End of Hyundai(1998-5-9)*/