📄 deblock.c
字号:
/*****************************************************************************
*
* T264 AVC CODEC
*
* Copyright(C) 2004-2005 llcc <lcgate1@yahoo.com.cn>
* 2004-2005 visionany <visionany@yahoo.com.cn>
* Added support for B frame,20041223 Cloud Wu<sywu@sohu.com>
* This program is free software ; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
****************************************************************************/
#include "stdio.h"
#include "T264.h"
#include "assert.h"
#define IS_INTRA(mode) (mode <= I_16x16)
static const uint8_t deblock_threshold_a[] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 4, 4, 5, 6, 7, 8, 9, 10, 12, 13,
15,17,20,22,25,28,32,36,40,45,50,56,63,71,
80,90,101,113,127,144,162,182,203,226,255,255
};
static const uint8_t deblock_threshold_b[] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,
6, 6, 7, 7, 8, 8, 9, 9,10,10,11,11,12,
12,13,13,14,14,15,15,16,16,17,17,18,18
};
static const uint8_t deblock_threshold_tc0[][3] =
{
{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 1 },
{ 0, 0, 1 }, { 0, 0, 1 }, { 0, 0, 1 }, { 0, 1, 1 }, { 0, 1, 1 }, { 1, 1, 1 },
{ 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 2 }, { 1, 1, 2 }, { 1, 1, 2 },
{ 1, 1, 2 }, { 1, 2, 3 }, { 1, 2, 3 }, { 2, 2, 3 }, { 2, 2, 4 }, { 2, 3, 4 },
{ 2, 3, 4 }, { 3, 3, 5 }, { 3, 4, 6 }, { 3, 4, 6 }, { 4, 5, 7 }, { 4, 5, 8 },
{ 4, 6, 9 }, { 5, 7,10 }, { 6, 8,11 }, { 6, 8,13 }, { 7,10,14 }, { 8,11,16 },
{ 9,12,18 }, {10,13,20 }, {11,15,23 }, {13,17,25 }
};
static void __inline
get_strength(T264_t* t, uint8_t bS[4], int32_t dir, int32_t edge, T264_mb_context_t* cur, T264_mb_context_t* prev)
{
int32_t row_stride, col_stride;
int32_t n;
if (dir == 0)
{
row_stride = 4;
col_stride = 1;
}
else
{
row_stride = 1;
col_stride = 4;
}
if (IS_INTRA(cur->mb_mode) || IS_INTRA(prev->mb_mode))
{
bS[0] = bS[1] = bS[2] = bS[3] = (edge == 0) ? 4 : 3;
}
else
{
for(n = 0 ; n < 4 ; n ++)
{
int32_t pos = n * row_stride + edge * col_stride;
int32_t pos_n;
if (cur == prev)
{ //If is macro blcok border
pos_n = dir == 0 ? pos - 1 : pos - 4;
}
else
{
pos_n = dir == 0 ? 4 * n + 3 : 12 + n;
}
if (cur->nnz[pos] || prev->nnz[pos_n])
{
bS[n] = 2;
}
else if (t->slice_type == SLICE_P)
{
int32_t ref, ref_n;
ref = cur->vec[0][pos].refno;
ref_n = prev->vec[0][pos_n].refno;
assert(cur->vec[0][pos].refno != -2);
assert(prev->vec[0][pos_n].refno != -2);
bS[n] = ((ref != ref_n) |
(ABS(cur->vec[0][pos].x - prev->vec[0][pos_n].x) >= 4) |
(ABS(cur->vec[0][pos].y - prev->vec[0][pos_n].y) >= 4));
}
else
{
int32_t ref0,ref1, ref_n0,ref_n1;
ref0 = cur->vec[0][pos].refno;
ref1 = cur->vec[1][pos].refno;
ref_n0 = prev->vec[0][pos_n].refno;
ref_n1 = prev->vec[1][pos_n].refno;
ref0 = ref0 < 0? -1 : ref0;
ref1 = ref1 < 0? -1 : ref1 + MAX_REFFRAMES;
ref_n0 = ref_n0 < 0? -1 : ref_n0;
ref_n1 = ref_n1 < 0? -1 : ref_n1 + MAX_REFFRAMES;
assert(ref0 > -1 || ref1 > -1);
if((ref0 == ref_n0 && ref1 == ref_n1) ||
(ref1 == ref_n0 && ref0 == ref_n1))
{
bS[n] = 0;
if(ref0 == ref1)
{ //if all use the same reference frame
bS[n] = (
(ABS(cur->vec[0][pos].x - prev->vec[0][pos_n].x) >= 4) |
(ABS(cur->vec[0][pos].y - prev->vec[0][pos_n].y) >= 4) |
(ABS(cur->vec[1][pos].x - prev->vec[1][pos_n].x) >= 4) |
(ABS(cur->vec[1][pos].y - prev->vec[1][pos_n].y) >= 4))
&&
(
(ABS(cur->vec[0][pos].x - prev->vec[1][pos_n].x) >= 4) |
(ABS(cur->vec[0][pos].y - prev->vec[1][pos_n].y) >= 4) |
(ABS(cur->vec[1][pos].x - prev->vec[0][pos_n].x) >= 4) |
(ABS(cur->vec[1][pos].y - prev->vec[0][pos_n].y) >= 4));
}else
{
if(ref0 == ref_n0)
{ //if list0 reference frame are the same
bS[n] =
(ABS(cur->vec[0][pos].x - prev->vec[0][pos_n].x) >= 4) |
(ABS(cur->vec[0][pos].y - prev->vec[0][pos_n].y) >= 4) |
(ABS(cur->vec[1][pos].x - prev->vec[1][pos_n].x) >= 4) |
(ABS(cur->vec[1][pos].y - prev->vec[1][pos_n].y) >= 4);
}else
{
bS[n] =
(ABS(cur->vec[0][pos].x - prev->vec[1][pos_n].x) >= 4) |
(ABS(cur->vec[0][pos].y - prev->vec[1][pos_n].y) >= 4) |
(ABS(cur->vec[1][pos].x - prev->vec[0][pos_n].x) >= 4) |
(ABS(cur->vec[1][pos].y - prev->vec[0][pos_n].y) >= 4);
}
}
}else
{
bS[n] =1;
}
}
}
}
}
static __inline void
EdgeLoopH(T264_t* t, uint8_t* dst, int32_t stride, uint8_t indexA, int32_t alpha, int32_t beta, uint8_t bS, int32_t is_chroma)
{
int32_t ap, aq, tmp;
uint8_t p[4];
uint8_t q[4];
q[0] = dst[0];
p[0] = dst[-1];
if (ABS(p[0] - q[0]) < alpha)
{
p[1] = dst[-2];
if (ABS(p[1] - p[0]) < beta)
{
q[1] = dst[1];
if (ABS(q[1] - q[0]) < beta)
{
if (bS < 4)
{
int32_t tc0, tc, delta;
tc0 = deblock_threshold_tc0[indexA][bS - 1];
if (is_chroma == 0)
{
q[2] = dst[2];
p[2] = dst[-3];
ap = ABS(p[2] - p[0]);
aq = ABS(q[2] - q[0]);
tc = tc0;
if (ap < beta)
{
dst[-2] = p[1] + clip3(((p[2] + ((p[0] + q[0] + 1) >> 1) - (p[1] << 1)) >> 1), -tc0, tc0);
tc ++;
}
if (aq < beta)
{
dst[1] = q[1] + clip3(((q[2] + ((p[0] + q[0] + 1) >> 1) - (q[1] << 1)) >> 1), -tc0, tc0);
tc ++;
}
}
else
{
tc = tc0 + 1;
}
delta = clip3(((((q[0] - p[0]) << 2) + (p[1] - q[1]) + 4) >> 3), -tc, tc);
tmp = p[0] + delta;
dst[-1] = CLIP1(tmp);
tmp = q[0] - delta;
dst[0] = CLIP1(tmp);
}
else
{
if (ABS(p[0] - q[0]) < ((alpha >> 2) + 2))
{
if (is_chroma == 0)
{
q[2] = dst[2];
p[2] = dst[-3];
ap = ABS(p[2] - p[0]);
aq = ABS(q[2] - q[0]);
if (ap < beta)
{
p[3] = dst[-4];
dst[-1] = (p[2] + 2 * p[1] + 2 * p[0] + 2 * q[0] + q[1] + 4) >> 3;
dst[-2] = (p[2] + p[1] + p[0] + q[0] + 2) >> 2;
dst[-3] = (2 * p[3] + 3 * p[2] + p[1] + p[0] + q[0] + 4) >> 3;
}
else
{
dst[-1] = (2 * p[1] + p[0] + q[1] + 2 ) >> 2;
}
if (aq < beta)
{
q[3] = dst[3];
dst[0] = (p[1] + 2 * p[0] + 2 * q[0] + 2 * q[1] + q[2] + 4) >> 3;
dst[1] = (p[0] + q[0] + q[1] + q[2] + 2) >> 2;
dst[2] = (2 * q[3] + 3 * q[2] + q[1] + q[0] + p[0] + 4) >> 3;
}
else
{
dst[0] = (2 * q[1] + q[0] + p[1] + 2 ) >> 2;
}
}
else
{
dst[-1] = (2 * p[1] + p[0] + q[1] + 2 ) >> 2;
dst[0] = (2 * q[1] + q[0] + p[1] + 2 ) >> 2;
}
}
else
{
dst[-1] = (2 * p[1] + p[0] + q[1] + 2 ) >> 2;
dst[0] = (2 * q[1] + q[0] + p[1] + 2 ) >> 2;
}
}
}
}
}
}
static __inline void
EdgeLoopV(T264_t* t, uint8_t* dst, int32_t stride, uint8_t indexA, int32_t alpha, int32_t beta, uint8_t bS, int32_t is_chroma)
{
int32_t ap, aq, tmp;
uint8_t p[4];
uint8_t q[4];
q[0] = dst[0];
p[0] = dst[-1 * stride];
if (ABS(p[0] - q[0]) < alpha)
{
p[1] = dst[-2 * stride];
if (ABS(p[1] - p[0]) < beta)
{
q[1] = dst[1 * stride];
if (ABS(q[1] - q[0]) < beta)
{
if (bS < 4)
{
int32_t tc0, tc, delta;
tc0 = deblock_threshold_tc0[indexA][bS - 1];
if (is_chroma == 0)
{
q[2] = dst[2 * stride];
p[2] = dst[-3 * stride];
ap = ABS(p[2] - p[0]);
aq = ABS(q[2] - q[0]);
tc = tc0;
if (ap < beta)
{
dst[-2 * stride] = p[1] + clip3(((p[2] + ((p[0] + q[0] + 1) >> 1) - (p[1] << 1)) >> 1), -tc0, tc0);
tc ++;
}
if (aq < beta)
{
dst[1 * stride] = q[1] + clip3(((q[2] + ((p[0] + q[0] + 1) >> 1) - (q[1] << 1)) >> 1), -tc0, tc0);
tc ++;
}
}
else
{
tc = tc0 + 1;
}
delta = clip3(((((q[0] - p[0]) << 2) + (p[1] - q[1]) + 4) >> 3), -tc, tc);
tmp = p[0] + delta;
dst[-1 * stride] = CLIP1(tmp);
tmp = q[0] - delta;
dst[0] = CLIP1(tmp);
}
else
{
if (ABS(p[0] - q[0]) < ((alpha >> 2) + 2))
{
if (is_chroma == 0)
{
q[2] = dst[2 * stride];
p[2] = dst[-3 * stride];
ap = ABS(p[2] - p[0]);
aq = ABS(q[2] - q[0]);
if (ap < beta)
{
p[3] = dst[-4 * stride];
dst[-1 * stride] = (p[2] + 2 * p[1] + 2 * p[0] + 2 * q[0] + q[1] + 4) >> 3;
dst[-2 * stride] = (p[2] + p[1] + p[0] + q[0] + 2) >> 2;
dst[-3 * stride] = (2 * p[3] + 3 * p[2] + p[1] + p[0] + q[0] + 4) >> 3;
}
else
{
dst[-1 * stride] = (2 * p[1] + p[0] + q[1] + 2 ) >> 2;
}
if (aq < beta)
{
q[3] = dst[3 * stride];
dst[0 * stride] = (p[1] + 2 * p[0] + 2 * q[0] + 2 * q[1] + q[2] + 4) >> 3;
dst[1 * stride] = (p[0] + q[0] + q[1] + q[2] + 2) >> 2;
dst[2 * stride] = (2 * q[3] + 3 * q[2] + q[1] + q[0] + p[0] + 4) >> 3;
}
else
{
dst[0] = (2 * q[1] + q[0] + p[1] + 2 ) >> 2;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -