deintl.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 2,337 行 · 第 1/4 页
CPP
2,337 行
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]);
#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);
#ifdef TIME_DEINTERLACE
num_avg++;
#endif
}
prev_mode = mode;
mode = next_mode;
fp1 += 4;
fp2 += 4;
fp3 += 4;
pfp1 += 4;
pfp2 += 4;
pfp3 += 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]);
#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);
#ifdef TIME_DEINTERLACE
num_avg++;
#endif
}
}
}
////////////////////////////////////////////////////////
//
// Deinterlace_I420_Advanced
//
// Slow deinterlacing of I420 data, using Edge Interpolation
//
////////////////////////////////////////////////////////
void
Deinterlace_I420_Advanced(unsigned char *frame, unsigned char *prev_frame, int pels, int lines, int pitch, int format)
{
int line, pel;
unsigned char *fpy, *pfpy;
unsigned char *fp1, *pfp1;
unsigned char *fp2, *pfp2;
unsigned char *fp3, *pfp3;
int edge1, edge2, pedge1, pedge2, diff1, diff2;
unsigned int a, c;
int tmp, pitch2;
pitch2= pitch<<1;
for (line = 1; line < lines - 2; line += 2)
{
fpy = frame + line*pitch;
// current frame
// current line
fp2 = fpy;
// prev line
fp1 = fp2 - pitch;
// next line
fp3 = fp2 + pitch;
// current frame
// previous frame
if (prev_frame != 0)
{
pfpy = prev_frame + line * pitch;
pfp2 = pfpy;
pfp1 = pfp2 - pitch;
pfp3 = pfp2 + pitch;
}
else
{
pfp2 = fp2;
pfp1 = fp1;
pfp3 = fp3;
}
// handle first pel
tmp = (*fp1 + *fp3) >> 1;
*fp2 = (unsigned char) tmp;
fp1++;
fp2++;
fp3++;
pfp1++;
edge1 = (*fp1) + *(fp1+1) +*(fp1+2);
edge2= (*fp3) + *(fp3+1) +*(fp3+2);
for (pel = 1; pel < pels-4; pel += 1)
{
edge1+=*(fp1+3);
edge2+=*(fp3+3);
tmp = (edge1 - edge2);
if( tmp > 160 || tmp < -160) {
// horiz
pfp3 = pfp1 + pitch2;
pedge1= *pfp1 + *(pfp1+1) + *(pfp1+2) + *(pfp1+3);
pedge2= *pfp3 + *(pfp3+1) + *(pfp3+2) + *(pfp3+3);
diff1 = (edge1 - pedge1);
if (diff1 < 0) diff1=-(diff1);
//diff1 = ABS(diff1);
diff2 = (edge2 - pedge2);
if (diff2 < 0) diff2=-(diff2);
//diff2 = ABS(diff2);
if ((diff1 + diff2) < 200) {
// not moving
*fp2 = MEDIAN_3(*fp1,*fp2,*fp3);
*(fp2+1) = MEDIAN_3(*(fp1+1),*(fp2+1),*(fp3+1));
#ifdef TIME_DEINTERLACE
num_med++;
#endif
edge1 -= *fp1;
edge2 -= *fp3;
fp1++;
fp2++;
fp3++;
pfp1++;
pel++;
edge1+=*(fp1+3);
edge2+=*(fp3+3);
} else {
tmp = *(fp2-1) + *fp1 + *fp3;
tmp *= 21845;
*fp2 = (unsigned char) (tmp >> 16);
//tmp = (*(fp2-1)<<1) + *fp1 + *fp3;
//*fp2 = (unsigned char) (tmp >> 2);
#ifdef TIME_DEINTERLACE
num_avg++;
#endif
}
} else {
// not horiz
// average
tmp = (*fp1 + *fp3) >> 1;
*fp2 = (unsigned char) tmp;
#ifdef TIME_DEINTERLACE
num_avg++;
#endif
}
edge1 -= (*fp1);
edge2 -= (*fp3);
fp1++;
fp2++;
fp3++;
pfp1++;
}
// handle last four pels
// last 4 pels
pfp3 = pfp1 + pitch2;
pedge1= *pfp1 + *(pfp1+1) + *(pfp1+2) + *(pfp1+3);
pedge2= *pfp3 + *(pfp3+1) + *(pfp3+2) + *(pfp3+3);
diff1 = (edge1 - pedge1);
diff1 = ABS(diff1);
diff2 = (edge2 - pedge2);
diff2 = ABS(diff2);
if ((diff1 + diff2) < 200) {
// not moving
// 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]);
#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);
#ifdef TIME_DEINTERLACE
num_avg++;
#endif
}
}
}
////////////////////////////////////////////////////////
//
// Deinterlace_I420
//
// Slow deinterlacing of I420 data, using both fields
//
////////////////////////////////////////////////////////
static void
Deinterlace_I420(unsigned char *frame, unsigned char *prev_frame, int pels, int lines, int pitch, int format)
{
int line, pel;
unsigned char *fp1,*pfp1; // line above
unsigned char *fp2,*pfp2; // current line
unsigned char *fp3,*pfp3; // line below
int tmp;
// Only handle RGB for now...
if (format != INTL_FORMAT_I420)
return;
for (line = 1; line < lines - 2; line += 2)
{
int a,b,c,d,e;
int mode = INTL_LINE_REMOVE_AVG;
// set pointers
fp1 = frame + (line - 1) * pitch;
fp2 = fp1 + pitch;
fp3 = fp2 + pitch;
if (prev_frame != 0)
{
pfp2 = prev_frame + line * pitch;
pfp1 = pfp1 - pitch;
pfp3 = pfp2 + pitch;
}
else
{
pfp2 = fp2;
pfp1 = fp1;
pfp3 = fp3;
}
// initialize
// a
tmp = (int)(*fp1++);
tmp -= (int)(*pfp1++);
a = DIFF_FCN(tmp);
tmp = (int)(*fp2++);
tmp -= (int)(*pfp2++);
a += DIFF_FCN(tmp);
tmp = (int)(*fp3++);
tmp -= (int)(*pfp3++);
a += DIFF_FCN(tmp);
// b
tmp = (int)(*fp1++);
tmp -= (int)(*pfp1++);
b = DIFF_FCN(tmp);
tmp = (int)(*fp2++);
tmp -= (int)(*pfp2++);
b += DIFF_FCN(tmp);
tmp = (int)(*fp3++);
tmp -= (int)(*pfp3++);
b += DIFF_FCN(tmp);
// c
tmp = (int)(*fp1);
tmp -= (int)(*pfp1);
c = DIFF_FCN(tmp);
tmp = (int)(*fp2);
tmp -= (int)(*pfp2);
c += DIFF_FCN(tmp);
tmp = (int)(*fp3);
tmp -= (int)(*pfp3);
c += DIFF_FCN(tmp);
// d
tmp = (int)(fp1[1]);
tmp -= (int)(pfp1[1]);
d = DIFF_FCN(tmp);
tmp = (int)(fp2[1]);
tmp -= (int)(pfp2[1]);
d += DIFF_FCN(tmp);
tmp = (int)(fp3[1]);
tmp -= (int)(pfp3[1]);
d += DIFF_FCN(tmp);
for (pel = 2; pel < pels - 2; pel++)
{
// e
tmp = (int)(fp1[2]);
tmp -= (int)(pfp1[2]);
e = DIFF_FCN(tmp);
tmp = (int)(fp2[2]);
tmp -= (int)(pfp2[2]);
e += DIFF_FCN(tmp);
tmp = (int)(fp3[2]);
tmp -= (int)(pfp3[2]);
e += DIFF_FCN(tmp);
// should we switch line removal mode?
if (mode == INTL_LINE_REMOVE_MEDIAN)
{
if (a + b + c + d + e > INTL_DIFF_THRESH)
{
a = MABS(fp1[-2] - fp1[+1]);
a += MABS(fp3[-2] - fp3[+1]);
a += MABS(fp1[-1] - fp1[+2]);
a += MABS(fp3[-1] - fp3[+2]);
a <<= 1;
a += MABS(fp1[-2] - fp3[-2]);
a += MABS(fp1[-1] - fp3[-1]);
a += MABS(fp1[+1] - fp3[+1]);
a += MABS(fp1[+2] - fp3[+2]);
if (a > 0)
{
mode = INTL_LINE_REMOVE_AVG;
}
}
}
else
{
if (a + b + c + d + e < INTL_DIFF_THRESH)
{
a = MABS(fp1[-2] - fp1[+1]);
a += MABS(fp3[-2] - fp3[+1]);
a += MABS(fp1[-1] - fp1[+2]);
a += MABS(fp3[-1] - fp3[+2]);
a <<= 1;
a += MABS(fp1[-2] - fp3[-2]);
a += MABS(fp1[-1] - fp3[-1]);
a += MABS(fp1[+1] - fp3[+1]);
a += MABS(fp1[+2] - fp3[+2]);
if (a < 0)
{
mode = INTL_LINE_REMOVE_MEDIAN;
}
}
}
if (mode == INTL_LINE_REMOVE_MEDIAN)
{
// median
fp2[0] = MEDIAN_3(fp1[0],fp2[0],fp3[0]);
}
else
{
// average
tmp = fp1[0];
tmp += fp3[0];
fp2[0] = (tmp >> 1);
}
// shift difference measures
a = b;
b = c;
c = d;
d = e;
// move pointers
fp1++;pfp1++;
fp2++;pfp2++;
fp3++;pfp3++;
}
}
}
////////////////////////////////////////////////////////
//
// Deinterlace_RGB24_Field
//
// Replaces 'frame' with only one field.
// The result is an image with dimesions pels x lines/2
//
////////////////////////////////////////////////////////
static void
Deinterlace_RGB24_Field(unsigned char *frame, unsigned char *prev_frame, int pels, int lines, int pitch, int format, int field)
{
int line;
unsigned char *in,*out;
lines >>= 1;
// R
in = frame + field * pitch;
out = frame;
for (line = field; line < lines; line++)
{
memcpy(out, in, pels); /* Flawfinder: ignore */
out += pitch;
in += (pitch << 1);
}
// G
in = frame + pels * (lines << 1);
out = frame + pels * lines;
for (line = 0; line < lines; line++)
{
memcpy(out, in, pels); /* Flawfinder: ignore */
out += pitch;
in += (pitch << 1);
}
// B
in = frame + pels * (lines << 1) * 2;
out = frame + pels * lines * 2;
for (line = 0; line < lines; line++)
{
memcpy(out, in, pels); /* Flawfinder: ignore */
out += pitch;
in += (pitch << 1);
}
}
////////////////////////////////////////////////////////
//
// Deinterlace_I420_Field
//
// Replaces 'frame' with only one field.
// The result is an image with dimesions pels x lines/2
//
////////////////////////////////////////////////////////
static void
Deinterlace_I420_Field(unsigned char *frame, unsigned char *prev_frame, int pels, int lines, int pitch, int format, int field)
{
register int line;
register unsigned char *in,*out;
int in_pitch;
int out_pitch;
int out_lines;
// Y
in_pitch = (pitch << 1);
out_pitch = pitch;
out_lines = (lines >> 1) & ~3;
in = frame + field * pitch;
out = frame;
for (line = 0; line < out_lines; line++)
{
memcpy(out, in, pels); /* Flawfinder: ignore */
out += out_pitch;
in += in_pitch;
}
pels >>= 1;
lines >>= 1;
in_pitch >>= 1;
out_pitch >>= 1;
out_lines >>= 1;
// U
in = frame + ((pels * lines) << 2);
out = frame + ((pels * out_lines) << 2);
for (line = 0; line < out_lines; line++)
{
memcpy(out, in, pels); /* Flawfinder: ignore */
out += out_pitch;
in += in_pitch;
}
// V
in = frame + pels * lines * 5;
out = frame + pels * out_lines * 5;
for (line = 0; line < out_lines; line++)
{
memcpy(out, in, pels); /* Flawfinder: ignore */
out += out_pitch;
in += in_pitch;
}
}
////////////////////////////////////////////////////////
//
// Deinterlace_I420_FlipFlop
//
// The Odd field is put at the top of the frame,
// the Even field is put up-side-down at the bottom.
//
////////////////////////////////////////////////////////
static void
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?