📄 postprocess.c
字号:
#include "postprocess.h"
#ifdef PP_SELF_CHECK
#include <stdio.h>
#endif
#define ABS(a) ( (a)>0 ? (a) : -(a) )
#define SIGN(a) ( (a)<0 ? -1 : 1 )
#define MIN(a, b) ( (a)<(b) ? (a) : (b) )
#define MAX(a, b) ( (a)>(b) ? (a) : (b) )
static int deblock_horiz_useDC(uint8_t *v, int stride) {
int eq_cnt, useDC;
int x, y;
#ifdef PP_SELF_CHECK
int eq_cnt2, j, k;
#endif
eq_cnt = 0;
for (y=0; y<4; y++) {
for (x=1; x<=7; x++) {
if (ABS(v[x+y*stride]-v[1+x+y*stride]) <= 1) eq_cnt--;
}
}
#ifdef PP_SELF_CHECK
eq_cnt2 = 0;
for (k=0; k<4; k++) {
for (j=1; j<=7; j++) {
if (ABS(v[j+k*stride]-v[1+j+k*stride]) <= 1) eq_cnt2--;
}
}
if (eq_cnt2 != eq_cnt) printf("ERROR: C version of useDC is incorrect\n");
#endif
useDC = eq_cnt <= -DEBLOCK_HORIZ_USEDC_THR;
return useDC;
}
static int deblock_horiz_DC_on(uint8_t *v, int stride, int QP) {
return (ABS(v[1]-v[8]) < 2*QP);
}
static void deblock_horiz_lpf9(uint8_t *v, int stride, int QP) {
int x, y, p1, p2, psum;
uint8_t *vv, vnew[9];
#ifdef PP_SELF_CHECK
uint8_t selfcheck[9];
int psum2;
uint8_t *vv2;
#endif
for (y=0; y<4; y++) {
p1 = (ABS(v[0+y*stride]-v[1+y*stride]) < QP ) ? v[0+y*stride] : v[1+y*stride];
p2 = (ABS(v[8+y*stride]-v[9+y*stride]) < QP ) ? v[9+y*stride] : v[8+y*stride];
#ifdef PP_SELF_CHECK
vv2 = &(v[y*stride]);
psum2 = p1 + p1 + p1 + vv2[1] + vv2[2] + vv2[3] + vv2[4] + 4;
selfcheck[1] = (((psum2 + vv2[1]) << 1) - (vv2[4] - vv2[5])) >> 4;
psum2 += vv2[5] - p1;
selfcheck[2] = (((psum2 + vv2[2]) << 1) - (vv2[5] - vv2[6])) >> 4;
psum2 += vv2[6] - p1;
selfcheck[3] = (((psum2 + vv2[3]) << 1) - (vv2[6] - vv2[7])) >> 4;
psum2 += vv2[7] - p1;
selfcheck[4] = (((psum2 + vv2[4]) << 1) + p1 - vv2[1] - (vv2[7] - vv2[8])) >> 4;
psum2 += vv2[8] - vv2[1];
selfcheck[5] = (((psum2 + vv2[5]) << 1) + (vv2[1] - vv2[2]) - vv2[8] + p2) >> 4;
psum2 += p2 - vv2[2];
selfcheck[6] = (((psum2 + vv2[6]) << 1) + (vv2[2] - vv2[3])) >> 4;
psum2 += p2 - vv2[3];
selfcheck[7] = (((psum2 + vv2[7]) << 1) + (vv2[3] - vv2[4])) >> 4;
psum2 += p2 - vv2[4];
selfcheck[8] = (((psum2 + vv2[8]) << 1) + (vv2[4] - vv2[5])) >> 4;
#endif
vv = &(v[y*stride]);
psum = p1 + p1 + p1 + vv[1] + vv[2] + vv[3] + vv[4] + 4;
vnew[1] = (((psum + vv[1]) << 1) - (vv[4] - vv[5])) >> 4;
psum += vv[5] - p1;
vnew[2] = (((psum + vv[2]) << 1) - (vv[5] - vv[6])) >> 4;
psum += vv[6] - p1;
vnew[3] = (((psum + vv[3]) << 1) - (vv[6] - vv[7])) >> 4;
psum += vv[7] - p1;
vnew[4] = (((psum + vv[4]) << 1) + p1 - vv[1] - (vv[7] - vv[8])) >> 4;
psum += vv[8] - vv[1];
vnew[5] = (((psum + vv[5]) << 1) + (vv[1] - vv[2]) - vv[8] + p2) >> 4;
psum += p2 - vv[2];
vnew[6] = (((psum + vv[6]) << 1) + (vv[2] - vv[3])) >> 4;
psum += p2 - vv[3];
vnew[7] = (((psum + vv[7]) << 1) + (vv[3] - vv[4])) >> 4;
psum += p2 - vv[4];
vnew[8] = (((psum + vv[8]) << 1) + (vv[4] - vv[5])) >> 4;
for (x=1; x<=8; x++) {
vv[x] = vnew[x];
}
#ifdef PP_SELF_CHECK
for (x=1; x<=8; x++) {
if (selfcheck[x] != v[x+y*stride]) printf("ERROR: C version of horiz lpf9 is incorrect\n");
}
#endif
}
}
static void deblock_horiz_default_filter(uint8_t *v, int stride, int QP) {
int a3_0, a3_1, a3_2, d;
int q1, q;
int y;
for (y=0; y<4; y++) {
q1 = v[4] - v[5];
q = q1 / 2;
if (q) {
a3_0 = 2*(v[3]-v[6]) - 5*q1;
if (ABS(a3_0) < 8*QP) {
a3_1 = 2*(v[1]-v[4]) + 5*(v[3]-v[2]);
a3_2 = 2*(v[5]-v[8]) + 5*(v[7]-v[8]);
d = ABS(a3_0) - MIN(ABS(a3_1), ABS(a3_2));
if (d > 0) {
d += d<<2;
d = (d + 32) >> 6;
if (d > 0) {
d *= SIGN(-a3_0);
if (q > 0) {
d = d<0 ? 0 : d;
d = d>q ? q : d;
} else {
d = d>0 ? 0 : d;
d = d<q ? q : d;
}
v[4] -= d;
v[5] += d;
}
}
}
}
#ifdef PP_SELF_CHECK
#endif;
v += stride;
}
}
void deblock_horiz(uint8_t *image, int width, int height, int stride, QP_STORE_T *QP_store, int QP_stride, int chroma) {
int x, y;
int QP;
uint8_t *v;
int useDC, DC_on;
for (y=0; y<height; y+=4) {
for (x=8; x<width; x+=8) {
QP = chroma ? QP_store[y/8*QP_stride+x/8]
: QP_store[y/16*QP_stride+x/16];
v = &(image[y*stride + x]) - 5;
useDC = deblock_horiz_useDC(v, stride);
if (useDC) {
DC_on = deblock_horiz_DC_on(v, stride, QP);
if (DC_on) {
deblock_horiz_lpf9(v, stride, QP);
#ifdef SHOWDECISIONS_H
if (!chromaFlag) {
v[0*stride + 4] =
v[1*stride + 4] =
v[2*stride + 4] =
v[3*stride + 4] = 255;
}
#endif
}
} else {
deblock_horiz_default_filter(v, stride, QP);
#ifdef SHOWDECISIONS_H
if (!chromaFlag) {
v[0*stride + 4] =
v[1*stride + 4] =
v[2*stride + 4] =
v[3*stride + 4] = 0;
}
#endif
}
}
}
}
static int deblock_vert_useDC(uint8_t *v, int stride) {
int eq_cnt, useDC, x, y;
#ifdef PP_SELF_CHECK
int useDC2, j, i;
#endif
#ifdef PP_SELF_CHECK
eq_cnt = 0;
for (j=1; j<8; j++) {
for (i=0; i<8; i++) {
if (ABS(v[j*stride+i] - v[(j+1)*stride+i]) <= 1) eq_cnt++;
}
}
useDC2 = (eq_cnt > DEBLOCK_VERT_USEDC_THR);
#endif
eq_cnt = 0;
for (y=1; y<8; y++) {
for (x=0; x<8; x++) {
if (ABS(v[y*stride+x] - v[(y+1)*stride+x]) <= 1) eq_cnt++;
}
}
useDC = (eq_cnt > DEBLOCK_VERT_USEDC_THR);
#ifdef PP_SELF_CHECK
if (useDC != useDC2) printf("ERROR: C version of useDC is incorrect\n");
#endif
return useDC;
}
static int deblock_vert_DC_on(uint8_t *v, int stride, int QP) {
int DC_on, x;
#ifdef PP_SELF_CHECK
int i, DC_on2;
#endif
#ifdef PP_SELF_CHECK
DC_on2 = 1;
for (i=0; i<8; i++) {
if (ABS(v[i+1*stride]-v[i+8*stride]) > 2 *QP) DC_on2 = 0;
}
#endif
DC_on = 1;
for (x=0; x<8; x++) {
if (ABS(v[x+1*stride]-v[x+8*stride]) > 2 *QP) DC_on = 0;
}
#ifdef PP_SELF_CHECK
if (DC_on != DC_on2) printf("ERROR: C version of DC_on is incorrect\n");
#endif
return DC_on;
}
void deblock_vert_lpf9(uint64_t *v_local, uint64_t *p1p2, uint8_t *v, int stride, int QP) {
int x, y;
int p1, p2, psum;
uint8_t *vv, vnew[9];
int l1 = 1 * stride;
int l2 = 2 * stride;
int l3 = 3 * stride;
int l4 = 4 * stride;
int l5 = 5 * stride;
int l6 = 6 * stride;
int l7 = 7 * stride;
int l8 = 8 * stride;
#ifdef PP_SELF_CHECK
int j, k;
uint8_t selfcheck[64];
#endif
#ifdef PP_SELF_CHECK
for (j=0; j<8; j++) {
vv = &(v[j]);
p1 = (ABS(vv[0*stride]-vv[1*stride]) < QP ) ? vv[0*stride] : vv[1*stride];
p2 = (ABS(vv[8*stride]-vv[9*stride]) < QP ) ? vv[9*stride] : vv[8*stride];
psum = p1 + p1 + p1 + vv[l1] + vv[l2] + vv[l3] + vv[l4] + 4;
selfcheck[j+8*0] = (((psum + vv[l1]) << 1) - (vv[l4] - vv[l5])) >> 4;
psum += vv[l5] - p1;
selfcheck[j+8*1] = (((psum + vv[l2]) << 1) - (vv[l5] - vv[l6])) >> 4;
psum += vv[l6] - p1;
selfcheck[j+8*2] = (((psum + vv[l3]) << 1) - (vv[l6] - vv[l7])) >> 4;
psum += vv[l7] - p1;
selfcheck[j+8*3] = (((psum + vv[l4]) << 1) + p1 - vv[l1] - (vv[l7] - vv[l8])) >> 4;
psum += vv[l8] - vv[l1];
selfcheck[j+8*4] = (((psum + vv[l5]) << 1) + (vv[l1] - vv[l2]) - vv[l8] + p2) >> 4;
psum += p2 - vv[l2];
selfcheck[j+8*5] = (((psum + vv[l6]) << 1) + (vv[l2] - vv[l3])) >> 4;
psum += p2 - vv[l3];
selfcheck[j+8*6] = (((psum + vv[l7]) << 1) + (vv[l3] - vv[l4])) >> 4;
psum += p2 - vv[l4];
selfcheck[j+8*7] = (((psum + vv[l8]) << 1) + (vv[l4] - vv[l5])) >> 4;
}
#endif
for (x=0; x<8; x++) {
vv = &(v[x]);
p1 = (ABS(vv[0*stride]-vv[1*stride]) < QP ) ? vv[0*stride] : vv[1*stride];
p2 = (ABS(vv[8*stride]-vv[9*stride]) < QP ) ? vv[9*stride] : vv[8*stride];
psum = p1 + p1 + p1 + vv[l1] + vv[l2] + vv[l3] + vv[l4] + 4;
vnew[1] = (((psum + vv[l1]) << 1) - (vv[l4] - vv[l5])) >> 4;
psum += vv[l5] - p1;
vnew[2] = (((psum + vv[l2]) << 1) - (vv[l5] - vv[l6])) >> 4;
psum += vv[l6] - p1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -