00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include "text_code.h"
00042 #include "text_dct.h"
00043
00044 #define BLOCK_SIZE 8
00045
00046 Void BlockPredict (SInt *curr,
00047 Int x_pos, Int y_pos, UInt width, Int fblock[][8]);
00048 Void BlockRebuild (SInt *rec_curr, SInt *comp, Int pred_type, Int max,
00049 Int x_pos, Int y_pos, UInt width, UInt edge, Int fblock[][8]);
00050 Void BlockQuantH263 (Int *coeff, Int QP, Int mode, Int type,
00051 Int *qcoeff, Int maxDC, Int image_type);
00052 Void BlockDequantH263 (Int *qcoeff, Int QP, Int mode, Int type,
00053 Int *rcoeff, Int image_type, Int short_video_header, Int bits_per_pixel);
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 Void CodeMB(Vop *curr, Vop *rec_curr, Vop *comp, Int x_pos, Int y_pos, UInt width,
00077 Int QP, Int Mode, Int *qcoeff)
00078 {
00079 Int k;
00080 Int fblock[6][8][8];
00081 Int coeff[384];
00082 Int *coeff_ind;
00083 Int *qcoeff_ind;
00084 Int* rcoeff_ind;
00085 Int x, y;
00086 SInt *current, *recon, *compensated = NULL;
00087 UInt xwidth;
00088 Int iblock[6][8][8];
00089 Int rcoeff[6*64];
00090 Int i, j;
00091 Int type;
00092
00093 SInt tmp[64];
00094 Int s;
00095
00096 int operation = curr->prediction_type;
00097
00098
00099
00100
00101
00102
00103
00104 Int max = GetVopBrightWhite(curr);
00105
00106
00107 coeff_ind = coeff;
00108 qcoeff_ind = qcoeff;
00109 rcoeff_ind = rcoeff;
00110
00111 for (k = 0; k < 6; k++)
00112 {
00113 switch (k)
00114 {
00115 case 0:
00116 x = x_pos;
00117 y = y_pos;
00118 xwidth = width;
00119 current = (SInt *) GetImageData (GetVopY (curr));
00120 break;
00121 case 1:
00122 x = x_pos + 8;
00123 y = y_pos;
00124 xwidth = width;
00125 current = (SInt *) GetImageData (GetVopY (curr));
00126 break;
00127 case 2:
00128 x = x_pos;
00129 y = y_pos + 8;
00130 xwidth = width;
00131 current = (SInt *) GetImageData (GetVopY (curr));
00132 break;
00133 case 3:
00134 x = x_pos + 8;
00135 y = y_pos + 8;
00136 xwidth = width;
00137 current = (SInt *) GetImageData (GetVopY (curr));
00138 break;
00139 case 4:
00140 x = x_pos / 2;
00141 y = y_pos / 2;
00142 xwidth = width / 2;
00143 current = (SInt *) GetImageData (GetVopU (curr));
00144 break;
00145 case 5:
00146 x = x_pos / 2;
00147 y = y_pos / 2;
00148 xwidth = width / 2;
00149 current = (SInt *) GetImageData (GetVopV (curr));
00150 break;
00151 default:
00152 break;
00153 }
00154 BlockPredict (current, x, y, xwidth, fblock[k]);
00155 }
00156
00157 for (k = 0; k < 6; k++)
00158 {
00159 s = 0;
00160 for (i = 0; i < 8; i++)
00161 for (j = 0; j < 8; j++)
00162 tmp[s++] = (SInt) fblock[k][i][j];
00163 #ifndef _MMX_
00164 fdct_enc(tmp);
00165 #else
00166 fdct_mm32(tmp);
00167 #endif
00168 for (s = 0; s < 64; s++)
00169 coeff_ind[s] = (Int) tmp[s];
00170
00171 if (k < 4) type = 1;
00172 else type = 2;
00173
00174
00175 BlockQuantH263(coeff_ind,QP,Mode,type,qcoeff_ind,
00176 GetVopBrightWhite(curr),1);
00177 BlockDequantH263(qcoeff_ind,QP,Mode,type,rcoeff_ind,1, 0, GetVopBitsPerPixel(curr));
00178
00179 for (s = 0; s < 64; s++)
00180 tmp[s] = (SInt) rcoeff_ind[s];
00181 #ifndef _MMX_
00182 idct_enc(tmp);
00183 #else
00184 Fast_IDCT(tmp);
00185 #endif
00186 s = 0;
00187 for (i = 0; i < 8; i++)
00188 for (j = 0; j < 8; j++)
00189 iblock[k][i][j] = (Int)tmp[s++];
00190
00191 coeff_ind += 64;
00192 qcoeff_ind += 64;
00193 rcoeff_ind += 64;
00194
00195 if (Mode == MODE_INTRA||Mode==MODE_INTRA_Q)
00196 for (i = 0; i < 8; i++)
00197 for (j = 0; j < 8; j ++)
00198 iblock[k][i][j] = MIN (GetVopBrightWhite(curr), MAX (0, iblock[k][i][j]));
00199
00200 switch (k)
00201 {
00202 case 0:
00203 case 1:
00204 case 2:
00205 continue;
00206
00207 case 3:
00208 recon = (SInt *) GetImageData (GetVopY (rec_curr));
00209 if (operation == P_VOP) compensated = (SInt *) GetImageData (GetVopY (comp));
00210 BlockRebuild (recon, compensated, operation, max, x_pos, y_pos, width, 16, iblock[0]);
00211 BlockRebuild (recon, compensated, operation, max, x_pos + 8, y_pos, width, 16, iblock[1]);
00212 BlockRebuild (recon, compensated, operation, max, x_pos, y_pos + 8, width, 16, iblock[2]);
00213 BlockRebuild (recon, compensated, operation, max, x_pos + 8, y_pos + 8, width, 16, iblock[3]);
00214 continue;
00215
00216 case 4:
00217 recon = (SInt *) GetImageData (GetVopU (rec_curr));
00218 if (operation == P_VOP) compensated = (SInt *) GetImageData (GetVopU (comp));
00219 BlockRebuild (recon, compensated, operation, max,
00220 x_pos/2, y_pos/2, width/2, 8, iblock[4]);
00221 continue;
00222
00223 case 5:
00224 recon = (SInt *) GetImageData (GetVopV (rec_curr));
00225 if (operation == P_VOP) compensated = (SInt *) GetImageData (GetVopV (comp));
00226 BlockRebuild (recon, compensated, operation, max,
00227 x_pos/2, y_pos/2, width/2, 8, iblock[5]);
00228 continue;
00229 }
00230 }
00231
00232 return;
00233 }
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 Void
00257 BlockPredict (SInt *curr, Int x_pos, Int y_pos,
00258 UInt width, Int fblock[][8])
00259 {
00260 Int i, j;
00261
00262 for (i = 0; i < 8; i++)
00263 {
00264 for (j = 0; j < 8; j++)
00265 {
00266 fblock[i][j] = curr[(y_pos+i)*width + x_pos+j];
00267 }
00268 }
00269 }
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292 Void
00293 BlockRebuild (SInt *rec_curr, SInt *comp, Int pred_type, Int max,
00294 Int x_pos, Int y_pos, UInt width, UInt edge, Int fblock[][8])
00295 {
00296
00297 Int i, j;
00298 SInt *rec;
00299 Int padded_width;
00300
00301 padded_width = width + 2 * edge;
00302 rec = rec_curr + edge * padded_width + edge;
00303
00304 if (pred_type == I_VOP)
00305 {
00306 SInt *p;
00307 p = rec + y_pos * padded_width + x_pos;
00308
00309 for (i = 0; i < 8; i++)
00310 {
00311 for (j = 0; j < 8; j++)
00312 {
00313 SInt temp = fblock[i][j];
00314 *(p++) = CLIP(temp, 0, max);
00315 }
00316
00317 p += padded_width - 8;
00318 }
00319 }
00320 else if (pred_type == P_VOP)
00321 {
00322 SInt *p, *pc;
00323 p = rec + y_pos * padded_width + x_pos;
00324 pc = comp + y_pos * width + x_pos;
00325
00326 for (i = 0; i < 8; i++)
00327 {
00328 for (j = 0; j < 8; j++)
00329 {
00330 SInt temp = *(pc++) + fblock[i][j];
00331 *(p++) = CLIP(temp, 0, max);
00332 }
00333
00334 p += padded_width - 8;
00335 pc += width - 8;
00336 }
00337 }
00338 }
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 Void
00359 BlockQuantH263 (Int *coeff,
00360 Int QP,
00361 Int mode,
00362 Int type,
00363 Int *qcoeff,
00364 Int maxDC,
00365 Int image_type)
00366 {
00367 Int i;
00368 Int level, result;
00369 Int step, offset;
00370 Int dc_scaler;
00371
00372
00373
00374
00375
00376
00377
00378
00379 if (!(QP > 0 && (QP < 32*image_type))) return;
00380 if (!(type == 1 || type == 2)) return;
00381
00382 if (mode == MODE_INTRA || mode == MODE_INTRA_Q)
00383 {
00384 dc_scaler = cal_dc_scaler(QP,type);
00385 qcoeff[0] = MAX(1,MIN(maxDC-1, (coeff[0] + dc_scaler/2)/dc_scaler));
00386
00387 step = 2 * QP;
00388 for (i = 1; i < 64; i++)
00389 {
00390 level = (abs(coeff[i])) / step;
00391 result = (coeff[i] >= 0) ? level : -level;
00392 qcoeff[i] = MIN(2047, MAX(-2048, result));
00393 }
00394 }
00395 else
00396 {
00397 step = 2 * QP;
00398 offset = QP / 2;
00399 for (i = 0; i < 64; i++)
00400 {
00401 level = (abs(coeff[i]) - offset) / step;
00402 result = (coeff[i] >= 0) ? level : -level;
00403 qcoeff[i] = MIN(2047, MAX(-2048, result));
00404 }
00405 }
00406
00407 return;
00408 }
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428 Void
00429 BlockDequantH263 (Int *qcoeff, Int QP, Int mode, Int type, Int *rcoeff,
00430 Int image_type, Int short_video_header, Int bits_per_pixel)
00431 {
00432 Int i;
00433 Int dc_scaler;
00434 Int lim;
00435
00436 lim = (1 << (bits_per_pixel + 3));
00437
00438 if (QP)
00439 {
00440 for (i = 0; i < 64; i++)
00441 {
00442 if (qcoeff[i])
00443 {
00444
00445 qcoeff[i] = MIN(2047, MAX(-2048, qcoeff[i] ));
00446 if ((QP % 2) == 1)
00447 rcoeff[i] = QP * (2*ABS(qcoeff[i]) + 1);
00448 else
00449 rcoeff[i] = QP * (2*ABS(qcoeff[i]) + 1) - 1;
00450 rcoeff[i] = SIGN(qcoeff[i]) * rcoeff[i];
00451 }
00452 else
00453 rcoeff[i] = 0;
00454 }
00455 if (mode == MODE_INTRA || mode == MODE_INTRA_Q)
00456 {
00457
00458 MOMCHECK(QP > 0 && (QP < 32*image_type));
00459 MOMCHECK(type == 1 || type == 2);
00460
00461 if (short_video_header)
00462 dc_scaler = 8;
00463 else
00464 dc_scaler = cal_dc_scaler(QP,type);
00465
00466 rcoeff[0] = qcoeff[0] * dc_scaler;
00467 }
00468 }
00469 else
00470 {
00471
00472 for (i = 0; i < 64; i++)
00473 {
00474 rcoeff[i] = qcoeff[i];
00475 }
00476
00477 if (mode == MODE_INTRA || mode == MODE_INTRA_Q)
00478 {
00479 rcoeff[0] = qcoeff[0]*8;
00480 }
00481 }
00482 for (i=0;i<64;i++)
00483 if (rcoeff[i]>(lim-1)) rcoeff[i]=(lim-1);
00484 else if (rcoeff[i]<(-lim)) rcoeff[i]=(-lim);
00485
00486 return;
00487 }
00488