/* ------------------------------------------------------------------ * Copyright (C) 1998-2009 PacketVideo * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. * See the License for the specific language governing permissions * and limitations under the License. * ------------------------------------------------------------------- */ #include "mp4dec_lib.h" #include "post_proc.h" #ifdef PV_POSTPROC_ON void Deringing_Luma( uint8 *Rec_Y, int width, int height, int16 *QP_store, int, uint8 *pp_mod) { /*---------------------------------------------------------------------------- ; Define all local variables ----------------------------------------------------------------------------*/ int thres[4], range[4], max_range_blk, max_thres_blk; int MB_V, MB_H, BLK_V, BLK_H; int v_blk, h_blk; int max_diff; int max_blk, min_blk; int v0, h0; uint8 *ptr; int thr, blks, incr; int mb_indx, blk_indx; /*---------------------------------------------------------------------------- ; Function body here ----------------------------------------------------------------------------*/ incr = width - BLKSIZE; /* Dering the first line of macro blocks */ for (MB_H = 0; MB_H < width; MB_H += MBSIZE) { max_diff = (QP_store[(MB_H)>>4] >> 2) + 4; /* threshold determination */ max_range_blk = max_thres_blk = 0; blks = 0; for (BLK_V = 0; BLK_V < MBSIZE; BLK_V += BLKSIZE) { for (BLK_H = 0; BLK_H < MBSIZE; BLK_H += BLKSIZE) { ptr = &Rec_Y[(int32)(BLK_V) * width + MB_H + BLK_H]; FindMaxMin(ptr, &min_blk, &max_blk, incr); thres[blks] = (max_blk + min_blk + 1) >> 1; range[blks] = max_blk - min_blk; if (range[blks] >= max_range_blk) { max_range_blk = range[blks]; max_thres_blk = thres[blks]; } blks++; } } blks = 0; for (v_blk = 0; v_blk < MBSIZE; v_blk += BLKSIZE) { v0 = ((v_blk - 1) >= 1) ? (v_blk - 1) : 1; for (h_blk = MB_H; h_blk < MB_H + MBSIZE; h_blk += BLKSIZE) { h0 = ((h_blk - 1) >= 1) ? (h_blk - 1) : 1; /* threshold rearrangement for flat region adjacent to non-flat region */ if (range[blks]<32 && max_range_blk >= 64) thres[blks] = max_thres_blk; /* threshold rearrangement for deblocking (blockiness annoying at DC dominant region) */ if (max_range_blk >= 16) { /* adaptive smoothing */ thr = thres[blks]; AdaptiveSmooth_NoMMX(Rec_Y, v0, h0, v_blk, h_blk, thr, width, max_diff); } blks++; } /* block level (Luminance) */ } } /* macroblock level */ /* Do the rest of the macro-block-lines */ for (MB_V = MBSIZE; MB_V < height; MB_V += MBSIZE) { /* First macro-block */ max_diff = (QP_store[((((int32)MB_V*width)>>4))>>4] >> 2) + 4; /* threshold determination */ max_range_blk = max_thres_blk = 0; blks = 0; for (BLK_V = 0; BLK_V < MBSIZE; BLK_V += BLKSIZE) { for (BLK_H = 0; BLK_H < MBSIZE; BLK_H += BLKSIZE) { ptr = &Rec_Y[(int32)(MB_V + BLK_V) * width + BLK_H]; FindMaxMin(ptr, &min_blk, &max_blk, incr); thres[blks] = (max_blk + min_blk + 1) >> 1; range[blks] = max_blk - min_blk; if (range[blks] >= max_range_blk) { max_range_blk = range[blks]; max_thres_blk = thres[blks]; } blks++; } } blks = 0; for (v_blk = MB_V; v_blk < MB_V + MBSIZE; v_blk += BLKSIZE) { v0 = v_blk - 1; for (h_blk = 0; h_blk < MBSIZE; h_blk += BLKSIZE) { h0 = ((h_blk - 1) >= 1) ? (h_blk - 1) : 1; /* threshold rearrangement for flat region adjacent to non-flat region */ if (range[blks]<32 && max_range_blk >= 64) thres[blks] = max_thres_blk; /* threshold rearrangement for deblocking (blockiness annoying at DC dominant region) */ if (max_range_blk >= 16) { /* adaptive smoothing */ thr = thres[blks]; AdaptiveSmooth_NoMMX(Rec_Y, v0, h0, v_blk, h_blk, thr, width, max_diff); } blks++; } } /* block level (Luminance) */ /* Rest of the macro-blocks */ for (MB_H = MBSIZE; MB_H < width; MB_H += MBSIZE) { max_diff = (QP_store[((((int32)MB_V*width)>>4)+MB_H)>>4] >> 2) + 4; /* threshold determination */ max_range_blk = max_thres_blk = 0; blks = 0; mb_indx = (MB_V / 8) * (width / 8) + MB_H / 8; for (BLK_V = 0; BLK_V < MBSIZE; BLK_V += BLKSIZE) { for (BLK_H = 0; BLK_H < MBSIZE; BLK_H += BLKSIZE) { blk_indx = mb_indx + (BLK_V / 8) * width / 8 + BLK_H / 8; /* Update based on pp_mod only */ if ((pp_mod[blk_indx]&0x4) != 0) { ptr = &Rec_Y[(int32)(MB_V + BLK_V) * width + MB_H + BLK_H]; FindMaxMin(ptr, &min_blk, &max_blk, incr); thres[blks] = (max_blk + min_blk + 1) >> 1; range[blks] = max_blk - min_blk; if (range[blks] >= max_range_blk) { max_range_blk = range[blks]; max_thres_blk = thres[blks]; } } blks++; } } blks = 0; for (v_blk = MB_V; v_blk < MB_V + MBSIZE; v_blk += BLKSIZE) { v0 = v_blk - 1; mb_indx = (v_blk / 8) * (width / 8); for (h_blk = MB_H; h_blk < MB_H + MBSIZE; h_blk += BLKSIZE) { h0 = h_blk - 1; blk_indx = mb_indx + h_blk / 8; if ((pp_mod[blk_indx]&0x4) != 0) { /* threshold rearrangement for flat region adjacent to non-flat region */ if (range[blks]<32 && max_range_blk >= 64) thres[blks] = max_thres_blk; /* threshold rearrangement for deblocking (blockiness annoying at DC dominant region) */ if (max_range_blk >= 16) { /* adaptive smoothing */ thr = thres[blks]; #ifdef NoMMX AdaptiveSmooth_NoMMX(Rec_Y, v0, h0, v_blk, h_blk, thr, width, max_diff); #else DeringAdaptiveSmoothMMX(&Rec_Y[v0*width+h0], width, thr, max_diff); #endif } } blks++; } } /* block level (Luminance) */ } /* macroblock level */ } /* macroblock level */ /*---------------------------------------------------------------------------- ; Return nothing or data or data pointer ----------------------------------------------------------------------------*/ return; } #endif