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++
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;
|
|
}
|