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