You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

126 lines
2.5 KiB
C++

// deinterlace.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "deinterlace.h"
/*
* ======== deinterlace_420psemi.c ========
* Video encoder algorithm.
*
* This file contains an implementation of the IVIDENC1 interface
* defined by XDM.
*/
#include <string.h>
typedef unsigned char uint8_t;
enum YUVFormat{
FMT_YUV411P,
FMT_YUV420P,
FMT_YUV420PSEMI,
FMT_YUV422P,
FMT_YUV444P};
#define MAX_NEG_CROP 0
static uint8_t ff_cropTbl[256 + 2 * MAX_NEG_CROP];
void Deinterlace_init(void)
{
int i;
for(i=0;i<256;i++) ff_cropTbl[i + MAX_NEG_CROP] = i;
for(i=0;i<MAX_NEG_CROP;i++) {
ff_cropTbl[i] = 0;
ff_cropTbl[i + MAX_NEG_CROP + 256] = 255;
}
}
void deinterlace_line(uint8_t *dst,
const uint8_t *lum_m4, const uint8_t *lum_m3,
const uint8_t *lum_m2, const uint8_t *lum_m1,
const uint8_t *lum,
int size)
{
const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
int sum;
for(;size > 0;size--) {
sum = -lum_m4[0];
sum += lum_m3[0] << 2;
sum += lum_m2[0] << 1;
sum += lum_m1[0] << 2;
sum += -lum[0];
dst[0] = cm[(sum + 4) >> 3];
if(sum >= 2040) dst[0] = 0xff;
lum_m4++;
lum_m3++;
lum_m2++;
lum_m1++;
lum++;
dst++;
}
}
void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
const uint8_t *src1, int src_wrap,
int width, int height)
{
const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
int y;
src_m2 = src1;
src_m1 = src1;
src_0=&src_m1[src_wrap];
src_p1=&src_0[src_wrap];
src_p2=&src_p1[src_wrap];
for(y=0;y<(height-2);y+=2) {
memcpy(dst,src_m1,width);
dst += dst_wrap;
deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
src_m2 = src_0;
src_m1 = src_p1;
src_0 = src_p2;
src_p1 += 2*src_wrap;
src_p2 += 2*src_wrap;
dst += dst_wrap;
}
memcpy(dst,src_m1,width);
dst += dst_wrap;
/* do last line */
deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
}
int Deinterlace_process(unsigned char *dst, unsigned char *src, int width, int height)
{
int i;
unsigned char *srcData[3]={NULL},*dstData[3]={NULL};
int iplane = 1;
if ((width & 3) != 0 || (height & 3) != 0)
return -1;
srcData[0] = src;
srcData[1] = src + width *height;
srcData[2] = src + ((width*height*5)>>2);
dstData[0] = dst;
dstData[1] = dst + width *height;
dstData[2] = dst + ((width*height*5)>>2);
for(i=0;i<iplane;i++) {
if (i == 1) {
width >>= 1;
height >>= 1;
}
deinterlace_bottom_field(dstData[i], width, srcData[i], width, width, height);
}
memset(dstData[1], 128, (width * height)>>1);
return 0;
}