blob: b5574b43d16027cb4ff54076c9aad812ce4d5898 [file] [log] [blame]
/* ------------------------------------------------------------------
* 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