📄 deintl.cpp
字号:
step2v_corr += MSQUARED(tmp);
tmp = f1[4] - f1[5];
step1h_corr += MSQUARED(tmp);
tmp = f1[4] - f1[6];
step2h_corr += MSQUARED(tmp);
tmp = f0[7] - f1[7];
step1v_corr += MSQUARED(tmp);
tmp = f0[7] - f2[7];
step2v_corr += MSQUARED(tmp);
tmp = f1[6] - f1[7];
step1h_corr += MSQUARED(tmp);
tmp = f1[6] - f1[8];
step2h_corr += MSQUARED(tmp);
f0 += 2 * pitch;
f1 += 2 * pitch;
f2 += 2 * pitch;
}
// These conditions indicate the block
// is very likely interlaced.
if (step1v_corr > step2v_corr &&
step1h_corr < (40*40*4*4) &&
step2v_corr < (40*40*4*4))
{
interlaced_blocks++;
}
// These conditions indicate the block
// is very likely progressive.
if (step1v_corr < 2 * step2v_corr &&
step1h_corr < (40*40*4*4) &&
step1v_corr < (40*40*4*4))
{
progressive_blocks++;
}
// Maintain totals
step1v_tot += step1v_corr;
step2v_tot += step2v_corr;
step1h_tot += step1h_corr;
step2h_tot += step2h_corr;
}
// Jump to the next 8x8 block
fp += 8 * SKIP_FACTOR;
pp += 8 * SKIP_FACTOR;
}
}
#if (SKIP_FACTOR != 1)
// If we're skipping some 8x8 block,
// acount for this by multiplying by skip factor
interlaced_blocks *= SKIP_FACTOR;
progressive_blocks *= SKIP_FACTOR;
step1v_tot *= SKIP_FACTOR;
step2v_tot *= SKIP_FACTOR;
step1h_tot *= SKIP_FACTOR;
step2h_tot *= SKIP_FACTOR;
#endif
// Scale these values.
// (Done to prevent overflow during later multiplies)
step1v_tot /= image_size;
step2v_tot /= image_size;
step1h_tot /= image_size;
step2h_tot /= image_size;
// Interlaced Tests
if (interlaced_blocks > progressive_blocks &&
interlaced_blocks > (image_size >> 12))
{
return INTL_WEAK_INTERLACE;
}
if (step1v_tot * step2h_tot > step1h_tot * step2v_tot &&
step1v_tot > step2v_tot &&
2 * interlaced_blocks > progressive_blocks &&
interlaced_blocks > (image_size >> 10))
{
return INTL_WEAK_INTERLACE;
}
// Progressive Tests
if (progressive_blocks > (image_size >> 10) &&
progressive_blocks > (interlaced_blocks << 4))
{
return INTL_WEAK_PROGRESSIVE;
}
return INTL_NO_DETECTION;
}
////////////////////////////////////////////////////////
//
// Deinterlace_RGB24_Fast
//
// Fast deinterlacing of RGB24 data, using both fields
//
////////////////////////////////////////////////////////
static void
Deinterlace_RGB24_Fast(unsigned char *frame, unsigned char *prev_frame, int pels, int lines, int pitch, int format)
{
int line, pel;
unsigned char *fp1,*pfp1;
unsigned char *fp2,*pfp2;
unsigned char *fp3,*pfp3;
unsigned char *fpr;
unsigned char *fpb;
// Only handle RGB for now...
if (format != INTL_FORMAT_RGB24)
return;
for (line = 1; line < lines - 2; line += 2)
{
unsigned int a,b,c,d,e,f;
int c_nw,c_ne,c_se,c_sw;
int diff,tmp;
int prev_mode = INTL_LINE_REMOVE_AVG;
int mode = INTL_LINE_REMOVE_AVG;
int next_mode = INTL_LINE_REMOVE_AVG;
// current frame
fpr = frame + line * pitch;
fp2 = fpr + pels * lines;
fp1 = fp2 - pitch;
fp3 = fp2 + pitch;
fpb = fp2 + pels * lines;
// previous frame
if (prev_frame != 0)
{
pfp2 = prev_frame + pels * lines + line * pitch;
pfp1 = pfp2 - pitch;
pfp3 = pfp2 + pitch;
}
else
{
pfp2 = fp2;
pfp1 = fp1;
pfp3 = fp3;
}
// initialize
for (pel = 0; pel < pels - 4; pel += 4)
{
// Load *next* 4 pels
a = ((unsigned int *)fp1)[1];
b = ((unsigned int *)fp2)[1];
c = ((unsigned int *)fp3)[1];
// Get corners
c_nw = (a >> 24);
c_ne = (a & 0xff);
c_sw = (c >> 24);
c_se = (c & 0xff);
// Edge detect
tmp = c_nw + c_ne - c_sw - c_se;
if ((tmp < 100) && (tmp > -100))
{
next_mode = INTL_LINE_REMOVE_AVG;
goto proc;
}
tmp = c_ne + c_se - c_nw - c_sw;
if (tmp > 100)
{
next_mode = INTL_LINE_REMOVE_AVG;
goto proc;
}
if (tmp < -100)
{
next_mode = INTL_LINE_REMOVE_AVG;
goto proc;
}
// Load previous pels
d = ((unsigned int *)pfp1)[1];
e = ((unsigned int *)pfp2)[1];
f = ((unsigned int *)pfp3)[1];
// Diff with previous pels
tmp = c_nw;
tmp -= (d >> 24);
diff = tmp ^ (tmp >> 31);
tmp = c_ne;
tmp -= (d & 0xff);
diff += tmp ^ (tmp >> 31);
if (diff > 100)
{
next_mode = INTL_LINE_REMOVE_AVG;
goto proc;
}
tmp = c_sw;
tmp -= (f >> 24);
diff += tmp ^ (tmp >> 31);
tmp = c_se;
tmp -= (f & 0xff);
diff += tmp ^ (tmp >> 31);
if (diff > 200)
{
next_mode = INTL_LINE_REMOVE_AVG;
goto proc;
}
tmp = (b >> 24);
tmp -= (e >> 24);
diff += tmp ^ (tmp >> 31);
tmp = (b & 0xff);
tmp -= (e & 0xff);
diff += tmp ^ (tmp >> 31);
if (diff > 300)
{
next_mode = INTL_LINE_REMOVE_AVG;
goto proc;
}
next_mode = INTL_LINE_REMOVE_MEDIAN;
proc:
if (mode == INTL_LINE_REMOVE_MEDIAN || prev_mode == INTL_LINE_REMOVE_MEDIAN || next_mode == INTL_LINE_REMOVE_MEDIAN)
{
// median
fp2[0] = MEDIAN_3(fp1[0],fp2[0],fp3[0]);
fp2[1] = MEDIAN_3(fp1[1],fp2[1],fp3[1]);
fp2[2] = MEDIAN_3(fp1[2],fp2[2],fp3[2]);
fp2[3] = MEDIAN_3(fp1[3],fp2[3],fp3[3]);
fpr[0] = MEDIAN_3(fpr[-pitch],fpr[0],fpr[pitch]);
fpr[1] = MEDIAN_3(fpr[-pitch+1],fpr[1],fpr[pitch+1]);
fpr[2] = MEDIAN_3(fpr[-pitch+2],fpr[2],fpr[pitch+2]);
fpr[3] = MEDIAN_3(fpr[-pitch+3],fpr[3],fpr[pitch+3]);
fpb[0] = MEDIAN_3(fpb[-pitch],fpb[0],fpb[pitch]);
fpb[1] = MEDIAN_3(fpb[-pitch+1],fpb[1],fpb[pitch+1]);
fpb[2] = MEDIAN_3(fpb[-pitch+2],fpb[2],fpb[pitch+2]);
fpb[3] = MEDIAN_3(fpb[-pitch+3],fpb[3],fpb[pitch+3]);
#ifdef TIME_DEINTERLACE
num_med++;
#endif
}
else
{
// average
a = ((unsigned int *)fp1)[0];
c = ((unsigned int *)fp3)[0];
((unsigned int*)fp2)[0] = (((a^c)>>1) & 0x7F7F7F7F) + (a&c);
a = ((unsigned int *)(fpr - pitch))[0];
c = ((unsigned int *)(fpr + pitch))[0];
((unsigned int*)fpr)[0] = (((a^c)>>1) & 0x7F7F7F7F) + (a&c);
a = ((unsigned int *)(fpb - pitch))[0];
c = ((unsigned int *)(fpb + pitch))[0];
((unsigned int*)fpb)[0] = (((a^c)>>1) & 0x7F7F7F7F) + (a&c);
#ifdef TIME_DEINTERLACE
num_avg++;
#endif
}
prev_mode = mode;
mode = next_mode;
fp1 += 4;
fp2 += 4;
fp3 += 4;
pfp1 += 4;
pfp2 += 4;
pfp3 += 4;
fpr += 4;
fpb += 4;
}
// last 4 pels
if (mode == INTL_LINE_REMOVE_MEDIAN || prev_mode == INTL_LINE_REMOVE_MEDIAN)
{
// median
fp2[0] = MEDIAN_3(fp1[0],fp2[0],fp3[0]);
fp2[1] = MEDIAN_3(fp1[1],fp2[1],fp3[1]);
fp2[2] = MEDIAN_3(fp1[2],fp2[2],fp3[2]);
fp2[3] = MEDIAN_3(fp1[3],fp2[3],fp3[3]);
fpr[0] = MEDIAN_3(fpr[-pitch],fpr[0],fpr[pitch]);
fpr[1] = MEDIAN_3(fpr[-pitch+1],fpr[1],fpr[pitch+1]);
fpr[2] = MEDIAN_3(fpr[-pitch+2],fpr[2],fpr[pitch+2]);
fpr[3] = MEDIAN_3(fpr[-pitch+3],fpr[3],fpr[pitch+3]);
fpb[0] = MEDIAN_3(fpb[-pitch],fpb[0],fpb[pitch]);
fpb[1] = MEDIAN_3(fpb[-pitch+1],fpb[1],fpb[pitch+1]);
fpb[2] = MEDIAN_3(fpb[-pitch+2],fpb[2],fpb[pitch+2]);
fpb[3] = MEDIAN_3(fpb[-pitch+3],fpb[3],fpb[pitch+3]);
#ifdef TIME_DEINTERLACE
num_med++;
#endif
}
else
{
// average
a = ((unsigned int *)fp1)[0];
c = ((unsigned int *)fp3)[0];
((unsigned int*)fp2)[0] = (((a^c)>>1) & 0x7F7F7F7F) + (a&c);
a = ((unsigned int *)(fpr - pitch))[0];
c = ((unsigned int *)(fpr + pitch))[0];
((unsigned int*)fpr)[0] = (((a^c)>>1) & 0x7F7F7F7F) + (a&c);
a = ((unsigned int *)(fpb - pitch))[0];
c = ((unsigned int *)(fpb + pitch))[0];
((unsigned int*)fpb)[0] = (((a^c)>>1) & 0x7F7F7F7F) + (a&c);
#ifdef TIME_DEINTERLACE
num_avg++;
#endif
}
}
}
////////////////////////////////////////////////////////
//
// Deinterlace_RGB24
//
// Slow deinterlacing of RGB24 data, using both fields
//
////////////////////////////////////////////////////////
static void
Deinterlace_RGB24(unsigned char *frame, unsigned char *prev_frame, int pels, int lines, int pitch, int format)
{
int line, pel;
unsigned char *fp1,*pfp1;
unsigned char *fp2,*pfp2;
unsigned char *fp3,*pfp3;
int tmp;
// Only handle RGB for now...
if (format != INTL_FORMAT_RGB24)
return;
for (line = 1; line < lines - 2; line += 2)
{
int a,b,c,d,e;
int mode = INTL_LINE_REMOVE_AVG;
fp1 = frame + line * pitch;
fp2 = frame + pels*lines + line * pitch;
fp3 = frame + 2 * pels*lines + line * pitch;
if (prev_frame != 0)
{
pfp1 = prev_frame + line * pitch;
pfp2 = prev_frame + pels*lines + line * pitch;
pfp3 = prev_frame + 2 * pels*lines + line * pitch;
}
else
{
pfp1 = fp1;
pfp2 = fp2;
pfp3 = fp3;
}
// initialize
tmp = (int)(fp1[-pitch]) + (int)(fp2[-pitch]) + (int)(fp3[-pitch]) - (int)(pfp1[-pitch]) - (int)(pfp2[-pitch]) - (int)(pfp3[-pitch]);
a = DIFF_FCN(tmp);
tmp = (int)(fp1[0]) + (int)(fp2[0]) + (int)(fp3[0]) - (int)(pfp1[0]) - (int)(pfp2[0]) - (int)(pfp3[0]);
a += DIFF_FCN(tmp);
tmp = (int)(fp1[pitch]) + (int)(fp2[pitch]) + (int)(fp3[pitch]) - (int)(pfp1[pitch]) - (int)(pfp2[pitch]) - (int)(pfp3[pitch]);
a += DIFF_FCN(tmp);
fp1++;pfp1++;
fp2++;pfp2++;
fp3++;pfp3++;
tmp = (int)(fp1[-pitch]) + (int)(fp2[-pitch]) + (int)(fp3[-pitch]) - (int)(pfp1[-pitch]) - (int)(pfp2[-pitch]) - (int)(pfp3[-pitch]);
b = DIFF_FCN(tmp);
tmp = (int)(fp1[0]) + (int)(fp2[0]) + (int)(fp3[0]) - (int)(pfp1[0]) - (int)(pfp2[0]) - (int)(pfp3[0]);
b += DIFF_FCN(tmp);
tmp = (int)(fp1[pitch]) + (int)(fp2[pitch]) + (int)(fp3[pitch]) - (int)(pfp1[pitch]) - (int)(pfp2[pitch]) - (int)(pfp3[pitch]);
b += DIFF_FCN(tmp);
fp1++;pfp1++;
fp2++;pfp2++;
fp3++;pfp3++;
tmp = (int)(fp1[-pitch]) + (int)(fp2[-pitch]) + (int)(fp3[-pitch]) - (int)(pfp1[-pitch]) - (int)(pfp2[-pitch]) - (int)(pfp3[-pitch]);
c = DIFF_FCN(tmp);
tmp = (int)(fp1[0]) + (int)(fp2[0]) + (int)(fp3[0]) - (int)(pfp1[0]) - (int)(pfp2[0]) - (int)(pfp3[0]);
c += DIFF_FCN(tmp);
tmp = (int)(fp1[pitch]) + (int)(fp2[pitch]) + (int)(fp3[pitch]) - (int)(pfp1[pitch]) - (int)(pfp2[pitch]) - (int)(pfp3[pitch]);
c += DIFF_FCN(tmp);
tmp = (int)(fp1[-pitch+1]) + (int)(fp2[-pitch+1]) + (int)(fp3[-pitch+1]) - (int)(pfp1[-pitch+1]) - (int)(pfp2[-pitch+1]) - (int)(pfp3[-pitch+1]);
d = DIFF_FCN(tmp);
tmp = (int)(fp1[1]) + (int)(fp2[1]) + (int)(fp3[1]) - (int)(pfp1[1]) - (int)(pfp2[1]) - (int)(pfp3[1]);
d += DIFF_FCN(tmp);
tmp = (int)(fp1[pitch+1]) + (int)(fp2[pitch+1]) + (int)(fp3[pitch+1]) - (int)(pfp1[pitch+1]) - (int)(pfp2[pitch+1]) - (int)(pfp3[pitch+1]);
d += DIFF_FCN(tmp);
for (pel = 2; pel < pels - 2; pel++)
{
tmp = (int)(fp1[-pitch+2]) + (int)(fp2[-pitch+2]) + (int)(fp3[-pitch+2]) - (int)(pfp1[-pitch+2]) - (int)(pfp2[-pitch+2]) - (int)(pfp3[-pitch+2]);
e = DIFF_FCN(tmp);
tmp = (int)(fp1[2]) + (int)(fp2[2]) + (int)(fp3[2]) - (int)(pfp1[2]) - (int)(pfp2[2]) - (int)(pfp3[2]);
e += DIFF_FCN(tmp);
tmp = (int)(fp1[pitch+2]) + (int)(fp2[pitch+2]) + (int)(fp3[pitch+2]) - (int)(pfp1[pitch+2]) - (int)(pfp2[pitch+2]) - (int)(pfp3[pitch+2]);
e += DIFF_FCN(tmp);
if (mode == INTL_LINE_REMOVE_MEDIAN)
{
if (a + b + c + d + e > INTL_DIFF_THRESH)
{
a = MABS(fp2[-pitch-2] - fp2[-pitch+1]);
a += MABS(fp2[pitch-2] - fp2[pitch+1]);
a += MABS(fp2[-pitch-1] - fp2[-pitch+2]);
a += MABS(fp2[pitch-1] - fp2[pitch+2]);
a <<= 1;
a -= MABS(fp2[-pitch-2] - fp2[pitch-2]);
a -= MABS(fp2[-pitch-1] - fp2[pitch-1]);
a -= MABS(fp2[-pitch+1] - fp2[pitch+1]);
a -= MABS(fp2[-pitch+2] - fp2[pitch+2]);
if (a > 0)
{
mode = INTL_LINE_REMOVE_AVG;
}
}
}
else
{
if (a + b + c + d + e < INTL_DIFF_THRESH)
{
a = MABS(fp2[-pitch-2] - fp2[-pitch+1]);
a += MABS(fp2[pitch-2] - fp2[pitch+1]);
a += MABS(fp2[-pitch-1] - fp2[-pitch+2]);
a += MABS(fp2[pitch-1] - fp2[pitch+2]);
a <<= 1;
a -= MABS(fp2[-pitch-2] - fp2[pitch-2]);
a -= MABS(fp2[-pitch-1] - fp2[pitch-1]);
a -= MABS(fp2[-pitch+1] - fp2[pitch+1]);
a -= MABS(fp2[-pitch+2] - fp2[pitch+2]);
if (a < 0)
{
mode = INTL_LINE_REMOVE_MEDIAN;
}
}
}
if (mode == INTL_LINE_REMOVE_MEDIAN)
{
// median
fp1[0] = MEDIAN_3(fp1[-pitch],fp1[0],fp1[pitch]);
fp2[0] = MEDIAN_3(fp2[-pitch],fp2[0],fp2[pitch]);
fp3[0] = MEDIAN_3(fp3[-pitch],fp3[0],fp3[pitch]);
}
else
{
// average
tmp = fp1[-pitch];
tmp += fp1[pitch];
fp1[0] = (tmp >> 1);
tmp = fp2[-pitch];
tmp += fp2[pitch];
fp2[0] = (tmp >> 1);
tmp = fp3[-pitch];
tmp += fp3[pitch];
fp3[0] = (tmp >> 1);
}
a = b;
b = c;
c = d;
d = e;
fp1++;pfp1++;
fp2++;pfp2++;
fp3++;pfp3++;
}
}
}
////////////////////////////////////////////////////////
//
// Deinterlace_I420_Fast
//
// Fast deinterlacing of I420 data, using both fields
//
////////////////////////////////////////////////////////
static void
Deinterlace_I420_Fast(unsigned char *frame, unsigned char *prev_frame, int pels, int lines, int pitch, int format)
{
int line, pel;
unsigned char *fp1,*pfp1;
unsigned char *fp2,*pfp2;
unsigned char *fp3,*pfp3;
// Only handle RGB for now...
if (format != INTL_FORMAT_I420)
return;
for (line = 1; line < lines - 2; line += 2)
{
unsigned int a,b,c,d,e,f;
int c_nw,c_ne,c_se,c_sw;
int diff,tmp;
int prev_mode = INTL_LINE_REMOVE_AVG;
int mode = INTL_LINE_REMOVE_AVG;
int next_mode = INTL_LINE_REMOVE_AVG;
// current frame
fp2 = frame + line * pitch;
fp1 = fp2 - pitch;
fp3 = fp2 + pitch;
// previous frame
if (prev_frame != 0)
{
pfp2 = prev_frame + line * pitch;
pfp1 = pfp2 - pitch;
pfp3 = pfp2 + pitch;
}
else
{
pfp2 = fp2;
pfp1 = fp1;
pfp3 = fp3;
}
// initialize
for (pel = 0; pel < pels - 4; pel += 4)
{
// Load *next* 4 pels
a = ((unsigned int *)fp1)[1];
b = ((unsigned int *)fp2)[1];
c = ((unsigned int *)fp3)[1];
// Get corners
c_nw = (a >> 24);
c_ne = (a & 0xff);
c_sw = (c >> 24);
c_se = (c & 0xff);
// Edge detect
tmp = c_nw + c_ne - c_sw - c_se;
if ((tmp < 100) && (tmp > -100))
{
next_mode = INTL_LINE_REMOVE_AVG;
goto proc;
}
tmp = c_ne + c_se - c_nw - c_sw;
if (tmp > 100)
{
next_mode = INTL_LINE_REMOVE_AVG;
goto proc;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -