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