📄 deintl.cpp
字号:
tmp = f0[3] - f2[3]; step2v_corr += MSQUARED(tmp); tmp = f1[2] - f1[3]; step1h_corr += MSQUARED(tmp); tmp = f1[2] - f1[4]; step2h_corr += MSQUARED(tmp); tmp = f0[5] - f1[5]; step1v_corr += MSQUARED(tmp); tmp = f0[5] - f2[5]; 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 voidDeinterlace_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 voidDeinterlace_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 voidDeinterlace_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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -