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