00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "global.h"
00016 #include "mb_access.h"
00017
00018
00019
00020
00021
00022
00023
00024 Boolean mb_is_available(int mbAddr, Macroblock *currMB)
00025 {
00026 ImageParameters *p_Img = currMB->p_Img;
00027 if ((mbAddr < 0) || (mbAddr > ((int)p_Img->PicSizeInMbs - 1)))
00028 return FALSE;
00029
00030
00031 if (!p_Img->DeblockCall)
00032 {
00033 if (p_Img->mb_data[mbAddr].slice_nr != currMB->slice_nr)
00034 return FALSE;
00035 }
00036
00037 return TRUE;
00038 }
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 void CheckAvailabilityOfNeighbors(Macroblock *currMB)
00049 {
00050 ImageParameters *p_Img = currMB->p_Img;
00051 const int mb_nr = currMB->mbAddrX;
00052
00053
00054 currMB->mb_up = NULL;
00055 currMB->mb_left = NULL;
00056
00057 if (p_Img->MbaffFrameFlag)
00058 {
00059 int cur_mb_pair = mb_nr >> 1;
00060 currMB->mbAddrA = 2 * (cur_mb_pair - 1);
00061 currMB->mbAddrB = 2 * (cur_mb_pair - p_Img->PicWidthInMbs);
00062 currMB->mbAddrC = 2 * (cur_mb_pair - p_Img->PicWidthInMbs + 1);
00063 currMB->mbAddrD = 2 * (cur_mb_pair - p_Img->PicWidthInMbs - 1);
00064
00065 currMB->mbAvailA = (byte) (mb_is_available(currMB->mbAddrA, currMB) && ((PicPos[cur_mb_pair ][0])!=0));
00066 currMB->mbAvailB = (byte) (mb_is_available(currMB->mbAddrB, currMB));
00067 currMB->mbAvailC = (byte) (mb_is_available(currMB->mbAddrC, currMB) && ((PicPos[cur_mb_pair + 1][0])!=0));
00068 currMB->mbAvailD = (byte) (mb_is_available(currMB->mbAddrD, currMB) && ((PicPos[cur_mb_pair ][0])!=0));
00069 }
00070 else
00071 {
00072 currMB->mbAddrA = mb_nr - 1;
00073 currMB->mbAddrB = mb_nr - p_Img->PicWidthInMbs;
00074 currMB->mbAddrC = mb_nr - p_Img->PicWidthInMbs + 1;
00075 currMB->mbAddrD = mb_nr - p_Img->PicWidthInMbs - 1;
00076
00077 currMB->mbAvailA = (byte) (mb_is_available(currMB->mbAddrA, currMB) && ((PicPos[mb_nr ][0])!=0));
00078 currMB->mbAvailB = (byte) (mb_is_available(currMB->mbAddrB, currMB));
00079 currMB->mbAvailC = (byte) (mb_is_available(currMB->mbAddrC, currMB) && ((PicPos[mb_nr + 1][0])!=0));
00080 currMB->mbAvailD = (byte) (mb_is_available(currMB->mbAddrD, currMB) && ((PicPos[mb_nr ][0])!=0));
00081 }
00082
00083 if (currMB->mbAvailA) currMB->mb_left = &(p_Img->mb_data[currMB->mbAddrA]);
00084 if (currMB->mbAvailB) currMB->mb_up = &(p_Img->mb_data[currMB->mbAddrB]);
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094 void get_mb_block_pos_normal (int mb_addr, short *x, short *y)
00095 {
00096 *x = (short) PicPos[ mb_addr ][0];
00097 *y = (short) PicPos[ mb_addr ][1];
00098 }
00099
00100
00101
00102
00103
00104
00105
00106
00107 void get_mb_block_pos_mbaff (int mb_addr, short *x, short *y)
00108 {
00109 *x = (short) PicPos[mb_addr>>1][0];
00110 *y = (short) ((PicPos[mb_addr>>1][1] << 1) + (mb_addr & 0x01));
00111 }
00112
00113
00114
00115
00116
00117
00118
00119 void get_mb_pos (ImageParameters *p_Img, int mb_addr, int mb_size[2], short *x, short *y)
00120 {
00121 p_Img->get_mb_block_pos(mb_addr, x, y);
00122
00123 (*x) = (short) ((*x) * mb_size[0]);
00124 (*y) = (short) ((*y) * mb_size[1]);
00125 }
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 void getNonAffNeighbour(Macroblock *currMB, int xN, int yN, int mb_size[2], PixelPos *pix)
00145 {
00146 ImageParameters *p_Img = currMB->p_Img;
00147 int maxW = mb_size[0], maxH = mb_size[1];
00148
00149 if ((xN < 0) && (yN < 0))
00150 {
00151 pix->mb_addr = currMB->mbAddrD;
00152 pix->available = currMB->mbAvailD;
00153 }
00154 else if ((xN < 0)&&((yN >= 0)&&(yN < maxH)))
00155 {
00156 pix->mb_addr = currMB->mbAddrA;
00157 pix->available = currMB->mbAvailA;
00158 }
00159 else if (((xN >= 0)&&(xN < maxW))&&(yN<0))
00160 {
00161 pix->mb_addr = currMB->mbAddrB;
00162 pix->available = currMB->mbAvailB;
00163 }
00164 else if (((xN >= 0)&&(xN < maxW))&&((yN >= 0)&&(yN < maxH)))
00165 {
00166 pix->mb_addr = currMB->mbAddrX;
00167 pix->available = TRUE;
00168 }
00169 else if ((xN >= maxW)&&(yN < 0))
00170 {
00171 pix->mb_addr = currMB->mbAddrC;
00172 pix->available = currMB->mbAvailC;
00173 }
00174 else
00175 {
00176 pix->available = FALSE;
00177 }
00178
00179 if (pix->available || p_Img->DeblockCall)
00180 {
00181 pix->x = (short) (xN & (maxW - 1));
00182 pix->pos_x = (short) (pix->x + PicPos[ pix->mb_addr ][0] * maxW);
00183 pix->y = (short) (yN & (maxH - 1));
00184 pix->pos_y = (short) (pix->y + PicPos[ pix->mb_addr ][1] * maxH);
00185 }
00186 }
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 void getAffNeighbour(Macroblock *currMB, int xN, int yN, int mb_size[2], PixelPos *pix)
00205 {
00206 ImageParameters *p_Img = currMB->p_Img;
00207 int maxW, maxH;
00208 int yM = -1;
00209
00210 maxW = mb_size[0];
00211 maxH = mb_size[1];
00212
00213
00214 pix->available = FALSE;
00215
00216 if(yN > (maxH - 1))
00217 {
00218 return;
00219 }
00220 if (xN > (maxW - 1) && yN >= 0 && yN < maxH)
00221 {
00222 return;
00223 }
00224
00225 if (xN < 0)
00226 {
00227 if (yN < 0)
00228 {
00229 if(!currMB->mb_field)
00230 {
00231
00232 if ((currMB->mbAddrX & 0x01) == 0)
00233 {
00234
00235 pix->mb_addr = currMB->mbAddrD + 1;
00236 pix->available = currMB->mbAvailD;
00237 yM = yN;
00238 }
00239 else
00240 {
00241
00242 pix->mb_addr = currMB->mbAddrA;
00243 pix->available = currMB->mbAvailA;
00244 if (currMB->mbAvailA)
00245 {
00246 if(!p_Img->mb_data[currMB->mbAddrA].mb_field)
00247 {
00248 yM = yN;
00249 }
00250 else
00251 {
00252 (pix->mb_addr)++;
00253 yM = (yN + maxH) >> 1;
00254 }
00255 }
00256 }
00257 }
00258 else
00259 {
00260
00261 if ((currMB->mbAddrX & 0x01) == 0)
00262 {
00263
00264 pix->mb_addr = currMB->mbAddrD;
00265 pix->available = currMB->mbAvailD;
00266 if (currMB->mbAvailD)
00267 {
00268 if(!p_Img->mb_data[currMB->mbAddrD].mb_field)
00269 {
00270 (pix->mb_addr)++;
00271 yM = 2 * yN;
00272 }
00273 else
00274 {
00275 yM = yN;
00276 }
00277 }
00278 }
00279 else
00280 {
00281
00282 pix->mb_addr = currMB->mbAddrD+1;
00283 pix->available = currMB->mbAvailD;
00284 yM = yN;
00285 }
00286 }
00287 }
00288 else
00289 {
00290 if (yN >= 0 && yN <maxH)
00291 {
00292 if (!currMB->mb_field)
00293 {
00294
00295 if ((currMB->mbAddrX & 0x01) == 0)
00296 {
00297
00298 pix->mb_addr = currMB->mbAddrA;
00299 pix->available = currMB->mbAvailA;
00300 if (currMB->mbAvailA)
00301 {
00302 if(!p_Img->mb_data[currMB->mbAddrA].mb_field)
00303 {
00304 yM = yN;
00305 }
00306 else
00307 {
00308 (pix->mb_addr)+= ((yN & 0x01) != 0);
00309 yM = yN >> 1;
00310 }
00311 }
00312 }
00313 else
00314 {
00315
00316 pix->mb_addr = currMB->mbAddrA;
00317 pix->available = currMB->mbAvailA;
00318 if (currMB->mbAvailA)
00319 {
00320 if(!p_Img->mb_data[currMB->mbAddrA].mb_field)
00321 {
00322 (pix->mb_addr)++;
00323 yM = yN;
00324 }
00325 else
00326 {
00327 (pix->mb_addr)+= ((yN & 0x01) != 0);
00328 yM = (yN + maxH) >> 1;
00329 }
00330 }
00331 }
00332 }
00333 else
00334 {
00335
00336 if ((currMB->mbAddrX & 0x01) == 0)
00337 {
00338
00339 pix->mb_addr = currMB->mbAddrA;
00340 pix->available = currMB->mbAvailA;
00341 if (currMB->mbAvailA)
00342 {
00343 if(!p_Img->mb_data[currMB->mbAddrA].mb_field)
00344 {
00345 if (yN < (maxH >> 1))
00346 {
00347 yM = yN << 1;
00348 }
00349 else
00350 {
00351 (pix->mb_addr)++;
00352 yM = (yN << 1 ) - maxH;
00353 }
00354 }
00355 else
00356 {
00357 yM = yN;
00358 }
00359 }
00360 }
00361 else
00362 {
00363
00364 pix->mb_addr = currMB->mbAddrA;
00365 pix->available = currMB->mbAvailA;
00366 if (currMB->mbAvailA)
00367 {
00368 if(!p_Img->mb_data[currMB->mbAddrA].mb_field)
00369 {
00370 if (yN < (maxH >> 1))
00371 {
00372 yM = (yN << 1) + 1;
00373 }
00374 else
00375 {
00376 (pix->mb_addr)++;
00377 yM = (yN << 1 ) + 1 - maxH;
00378 }
00379 }
00380 else
00381 {
00382 (pix->mb_addr)++;
00383 yM = yN;
00384 }
00385 }
00386 }
00387 }
00388 }
00389 }
00390 }
00391 else
00392 {
00393 if (xN >= 0 && xN < maxW)
00394 {
00395 if (yN<0)
00396 {
00397 if (!currMB->mb_field)
00398 {
00399
00400 if ((currMB->mbAddrX & 0x01) == 0)
00401 {
00402
00403 pix->mb_addr = currMB->mbAddrB;
00404
00405
00406 if (currMB->mbAvailB)
00407 {
00408 if (!(p_Img->DeblockCall == 1 && (p_Img->mb_data[currMB->mbAddrB]).mb_field))
00409 pix->mb_addr += 1;
00410 }
00411
00412 pix->available = currMB->mbAvailB;
00413 yM = yN;
00414 }
00415 else
00416 {
00417
00418 pix->mb_addr = currMB->mbAddrX - 1;
00419 pix->available = TRUE;
00420 yM = yN;
00421 }
00422 }
00423 else
00424 {
00425
00426 if ((currMB->mbAddrX & 0x01) == 0)
00427 {
00428
00429 pix->mb_addr = currMB->mbAddrB;
00430 pix->available = currMB->mbAvailB;
00431 if (currMB->mbAvailB)
00432 {
00433 if(!p_Img->mb_data[currMB->mbAddrB].mb_field)
00434 {
00435 (pix->mb_addr)++;
00436 yM = 2* yN;
00437 }
00438 else
00439 {
00440 yM = yN;
00441 }
00442 }
00443 }
00444 else
00445 {
00446
00447 pix->mb_addr = currMB->mbAddrB + 1;
00448 pix->available = currMB->mbAvailB;
00449 yM = yN;
00450 }
00451 }
00452 }
00453 else
00454 {
00455
00456
00457 if (yN == 0 && p_Img->DeblockCall == 2)
00458 {
00459 pix->mb_addr = currMB->mbAddrB + 1;
00460 pix->available = TRUE;
00461 yM = yN - 1;
00462 }
00463
00464 else if ((yN >= 0) && (yN <maxH))
00465 {
00466 pix->mb_addr = currMB->mbAddrX;
00467 pix->available = TRUE;
00468 yM = yN;
00469 }
00470 }
00471 }
00472 else
00473 {
00474 if(yN < 0)
00475 {
00476 if (!currMB->mb_field)
00477 {
00478
00479 if ((currMB->mbAddrX & 0x01) == 0)
00480 {
00481
00482 pix->mb_addr = currMB->mbAddrC + 1;
00483 pix->available = currMB->mbAvailC;
00484 yM = yN;
00485 }
00486 else
00487 {
00488
00489 pix->available = FALSE;
00490 }
00491 }
00492 else
00493 {
00494
00495 if ((currMB->mbAddrX & 0x01) == 0)
00496 {
00497
00498 pix->mb_addr = currMB->mbAddrC;
00499 pix->available = currMB->mbAvailC;
00500 if (currMB->mbAvailC)
00501 {
00502 if(!p_Img->mb_data[currMB->mbAddrC].mb_field)
00503 {
00504 (pix->mb_addr)++;
00505 yM = 2* yN;
00506 }
00507 else
00508 {
00509 yM = yN;
00510 }
00511 }
00512 }
00513 else
00514 {
00515
00516 pix->mb_addr = currMB->mbAddrC + 1;
00517 pix->available = currMB->mbAvailC;
00518 yM = yN;
00519 }
00520 }
00521 }
00522 }
00523 }
00524 if (pix->available || p_Img->DeblockCall)
00525 {
00526 pix->x = (short) (xN & (maxW - 1));
00527 pix->y = (short) (yM & (maxH - 1));
00528 get_mb_pos(p_Img, pix->mb_addr, mb_size, &(pix->pos_x), &(pix->pos_y));
00529 pix->pos_x = pix->pos_x + pix->x;
00530 pix->pos_y = pix->pos_y + pix->y;
00531 }
00532 }
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551 void get4x4Neighbour (Macroblock *currMB, int block_x, int block_y, int mb_size[2], PixelPos *pix)
00552 {
00553 currMB->p_Img->getNeighbour(currMB, block_x, block_y, mb_size, pix);
00554
00555 if (pix->available)
00556 {
00557 pix->x >>= 2;
00558 pix->y >>= 2;
00559 pix->pos_x >>= 2;
00560 pix->pos_y >>= 2;
00561 }
00562 }