请教大家,这个程序要怎么将其改成不是静止图像灰度变换而是视频灰度变换呢?
/*
* Copyright 2007 by Techshine Incorporated.
* All rights reserved.
* Author: lyj
*/
/*
* Video color2gray Test
*
*/
#include "tvp5146.h"
#define COLORBARS 1
#define LOOPBACK 0
#define SVIDEO_OUT 1
#define COMPONENT_OUT 0
typedef struct __RGBC
{
Uint8 Red;
Uint8 Green;
Uint8 Blue;
} RGBCOLOR;
void PictureGray(Uint32 memaddr);
/* ———————————————————————— *
* *
* vpfe_init( ) *
* *
* NTSC: *
* Width: 720 *
* Height: 480 *
* *
* *
* ———————————————————————— */
void vpfe_init(Uint32 buffer, Uint32 width, Uint32 height)
{ //同步、模式设置
VPFE_CCDC_SYN_MODE = 0 //0x00032F84; // interlaced, with VD pority as negative
| (0 << 19) //使能 SDRAM端口输出到resizer的输入,0=disable
| (0 << 18) //使能 视频口video port,输出到SDRAM,0=disable
| (1 << 17) //数据写使能,控制CCD列数据是否写入DDR,0=disable
| (1 << 16) //vd/hd使能,如果hd、vd定义为输出,那么内部产生时序,否则外部产生
| (0 << 15) //Field状态,表明当前的field状态,0=奇场,1=偶场
| (0 << 14) //3 tap低通滤波器,0=off
| (2 << 12) //INPMOD 数据输入模式,0=CCD Raw,1=YCbCr 16bit,2=YCbCr 8bit,3保留
| (1 << 11) //每个象素的包大小,0=16bit/pixel,1=8bit/pixel
| (7 << 8) //ccd 数据宽度,只有INPMOD=0(12bit-13bit)时有效
// 0=16bit,1=15bit,2=14bit,3=13bit,4=12bit
// 5=11bit,6=10bit,7=8bit
| (1 << 7) //传感器场模式,0=逐行扫描,1=隔行
| (0 << 6) //CCD数据极性
| (0 << 5) //外部WEN信号选择,如果VDHDEN=1(16bit),设置此位将使CCD数据加载到DDR
// 0=不使用
| (0 << 4) //场 指示器极性,0=正极,1=负极
| (0 << 3) //HD同步极性,0=正极,1=负极
| (1 << 2) //VD同步极性,0=正极,1=负极
| (0 << 1) //场ID方向,0=输入,1=输出
| (0); //VD、HD同步方向,0=输入,1=输出
VPFE_CCDC_HD_VD_WID = 0; //HD,VD信号脉冲宽度寄存器
VPFE_CCDC_PIX_LINES = 0x02CF020D; //每行的水平象素,及一帧的行数
//0|(0x2cf<<16) //每行的水平象素719+1=720
//|(0x20d) //每帧或每场的半行数525+1=526
/*
* sph = 1, nph = 1440, according to page 32-33 of the CCDC spec
* for BT.656 mode, this setting captures only the 720×480 of the
* active NTSV video window
*/
VPFE_CCDC_HORZ_INFO = width << 1; // Horizontal lines
//水平象素信息,(31-16)=开始象素,(14-0)=输入到DDR的每行象素个数
VPFE_CCDC_HSIZE_OFF = width << 1; // Horizontal line offset
// 水平大小,(15-0)=每行的地址偏移,即跳行到DDR2读取数据?
// 5 lsb 忽略,最好是256字节的倍数
VPFE_CCDC_VERT_START = 0; // Vertical start line
// 垂直线开始象素(16-31)=SLV0(Field0),(0-14)=SLV1(Field0)
// 设定数据输入到DDR的开始行
VPFE_CCDC_VERT_LINES = height >> 1; // Vertical lines(14bit-0)
// 垂直线的线数
VPFE_CCDC_CULLING = 0xFFFF00FF; // Disable cullng,水平及垂直方向的选择方式
//(31-24)=偶场的水平选择,(23-16)=奇场的水平选择
// (15-8)=保留,(7-0)=垂直选择模式
/*
* Interleave the two fields
*/
VPFE_CCDC_SDOFST = 0 //0x00000249; //DDR线偏移
| (0 << 14) //场标志信号翻转,0=正常
| (0 << 12) //场线偏移,0=+1线,1=+2线,2=+3线,3=+4线,
| (1 << 9) //偶线和偶场的线偏移,0=+1,1=+2,2=+3,3=+4,4=-1,
// 5=-2,6=-3,7=-4,
| (1 << 6) //奇线和偶场的线偏移,0=+1,1=+2,2=+3,3=+4,4=-1,
// 5=-2,6=-3,7=-4,
| (1 << 3) //偶线和奇场的线偏移,0=+1,1=+2,2=+3,3=+4,4=-1,
// 5=-2,6=-3,7=-4,
| (1 << 0); //奇线和奇场的线偏移,0=+1,1=+2,2=+3,3=+4,4=-1,
// 5=-2,6=-3,7=-4,
VPFE_CCDC_SDR_ADDR = buffer; //buffer DDR地址,最低5位忽略
VPFE_CCDC_CLAMP = 0 //; //可选的黑色箝位设置
| (0 << 31) //CLAMPEN ,CLAMP使能,0=禁止
| (0 << 28) //采样象素长度,0=1pixel,为2^N(次幂),5-7保留
| (0 << 25) //采样线长度,0=1 line,为2^N(次幂),5-7保留
| (0 << 10) //采样的开始象素
| (0 << 0); //bit4-bit0,平均增益
VPFE_CCDC_DCSUB = 0; //CCD数据要减去的值,当CLAMPEN=0时有效
VPFE_CCDC_COLPTN = 0xEE44EE44; //调色板设置
//0|(0<<30) //第三线调色板,3个象素,0=R,1=Gr,2=Gb,3=B
//|(0<<28) //CP3LPC2,象素个数=2
//|(0<<26) //CP3LPC1,象素个数=1
// |(0<<24) //CP3LPC0,象素个数=0
// |(0<<22) //第二线调色板
// |(0<<20)
// |(0<<18)
// |(0<<16)
// |(0<<14) //第一线调色板
// |(0<<12)
// |(0<<10)
// |(0<<8)
// |(0<<6) //第0线调色板
// |(0<<4)
// |(0<<2)
// |(0<<0);
VPFE_CCDC_BLKCMP = 0; //黑色补偿
//0|(0<<24) //R红色
//|(0<<16) //Gr
// |(0<<8) //Gb
// |(0<<0); //B蓝色
VPFE_CCDC_FPC_ADDR = 0x86800000; //不知道干吗用的
VPFE_CCDC_FPC = 0;
VPFE_CCDC_VDINT = 0; //VD中断时序,(30-16)=VDINT0,(14-0)=VDINT1
VPFE_CCDC_ALAW = 0; //a 率设置
VPFE_CCDC_REC656IF = 0 //0x00000003; //rec656接口
| (1 << 1) //FVH错误纠正使能
| (1 << 0); //Rec656接口使能
/*
* Input format is Cb:Y:Cr:Y, w/ Y in odd-pixel position
*/
VPFE_CCDC_CCDCFG = 0 //0x00000800; //CCD配置寄存器
| (0 << 15) //使能VSYNC内部的锁存功能,0=使用VSYNC锁存
| (0 << 13) //MSBINVI,色度输入信号最高位是否在SDRAM中翻转,0=正常
| (0 << 12) //DDR的字节是否交换,如果字节包已经使能,象素个数必须为偶数
// 0=正常
| (1 << 11) //YCbCr 8bit输入时Y的位置,0=偶像素,1=奇象素
| (0 << 8) //指定CCD有效范围,0=当WEN为逻辑“与”时内部信号有效,反之为“”
| (0 << 6) //FID检测,0=VSYNC时序锁存FID信号,1=不锁存,2=VD边缘锁存,3=VD、HD的相位决定
| (0 << 5) //CCIR656输入数据宽度,0=8bit,1=10bit
| (0 << 4) //YCINSWP,YI输入和CI引脚输入交换,0=不交换
| 0;
VPFE_CCDC_FMTCFG = 0; //数据重新格式化、图象口配置
//0|(0<<16) //图象口数据准备好频率,跟内核频率有关,0=CoreClock*1/2=75MHz
//|(0<<15) //video port 使能
// |(0<<12) //video port输入选择,0=bit 15~6
// |0;
VPFE_CCDC_FMT_HORZ = 0 //0x000002D0; //数据重新格式化、图象输入接口水平信息
| (0 << 16) //bit31~29保留,从HD开始的水平开始象素
| (0x2D0 << 0) //bit15~13保留,水平方向的象素个数=0x2d0=720
| 0;
VPFE_CCDC_FMT_VERT = 0 //0x0000020E; //数据重新格式化、图象输入接口垂直信息
| (0 << 16) //bit31~29保留,从vd开始的水平开始象素
| (0x20e << 0) //bit15~13保留,水平方向的象素个数=0x20e=526
| 0;
VPFE_CCDC_FMT_ADDR0 = 0;
VPFE_CCDC_FMT_ADDR1 = 0;
VPFE_CCDC_FMT_ADDR2 = 0;
VPFE_CCDC_FMT_ADDR3 = 0;
VPFE_CCDC_FMT_ADDR4 = 0;
VPFE_CCDC_FMT_ADDR5 = 0;
VPFE_CCDC_FMT_ADDR6 = 0;
VPFE_CCDC_FMT_ADDR7 = 0;
VPFE_CCDC_PRGEVEN_0 = 0;
VPFE_CCDC_PRGEVEN_1 = 0;
VPFE_CCDC_PRGODD_0 = 0;
VPFE_CCDC_PRGODD_1 = 0;
VPFE_CCDC_VP_OUT = 0 //0x041A2D00; //video port输出设置
| (0x20d << 17) //被时钟输出到video port的垂直线数=0x20d=525
| (0x2d0 << 4) //被时钟输出到video port的水平线数=0x2d0=720
| (0 << 0); //每个输出行的水平开始象素=0
VPFE_CCDC_PCR = 0x00000001; // Enable CCDC,bit1=是否busy,bit0=enable
//如果禁止的话,CCDC会向DSP发送中断,不需要中断需要配置INTC
}
/* ———————————————————————— *
* *
* vpbe_init( ) *
* *
* NTSC: *
* Width: 720 *
* Height: 480 *
* *
* *
* ———————————————————————— */
void vpbe_init(Uint32 buffer, Uint32 width, Uint32 height,
Uint32 colorbar_loopback_mode, Uint32 ntsc_pal_mode,
Uint32 output_mode)
{
Int16 basep_x;
Int16 basep_y;
RGBCOLOR rc;
if(ntsc_pal_mode == NTSC)
{
basep_x = 0x7A; // 122
basep_y = 0x12; // 18
}
else
{
basep_x = 0x84; // 132
basep_y = 0x16; // 22
}
/*
* Setup VPBE
*/
VPSS_CLK_CTRL = 0x00000018; // Enable DAC and VENC clock, both at 27 MHz
VPBE_PCR = 0; // No clock div, clock enable
/*
* Setup OSD
*/
VPBE_OSD_MODE = 0 //0x000000fc; // osd模式寄存器
// 最后8位指定背景色地址(ROM0)
| (0 << 15) //cb/cr顺序,0=cb/cr,1=cr/cb (修改这个1会把背景变红)
| (0 << 14) //osd窗口垂直扩展使能,如果使能,bitmap窗口
//Y值将延伸为6/5。0= *1,1=*6/5
| (0 << 13) //osd窗口水平扩展使能,如果使能,bitmap窗口
//X值将延伸为9/8。可用于pal和ntsc切换
| (0 << 12) //延伸滤波使能,14、13位使能才有用,或者video串口
//smoothing已经设置,小心使用
| (0 << 11) //video窗口,类似14位
| (0 << 10) //video窗口,类似13位
| (0 << 9) //field(场信号)翻转=1
| (0 << 8) //背景颜色表选择,0=ROM,1=RAM
| (0xfd << 0) //CLUT(color look-up table)背景颜色查找表地址
; //这是一部分图象不显示时出现的颜色
//–OSD窗口0、1设置 ,!!!!暂时不用!!!!
VPBE_OSD_OSDWIN0MD = 0 | // Disable both osd windows and cursor window
(0 << 13) | //RGB0E RGB输入还是BITMAP输入
// 0=bitmap,1=16bit RGB,如果此位设置,
// **#####**那么WINDOW1的该位不能为1 **#####**
(0 << 12) | //CLUTS0, OSDWINDOW0的颜色查找表位置,0=rom,1=RAM
(0 << 10) | //OHZ0 osd窗口0水平放大倍数(1、2、4)
(0 << 8) | //OVZ0 osd窗口0垂直放大倍数
(0 << 6) | //BMW0 bitmap位宽0=1,1=2,2=4,3=8
(0 << 3) | //BLND0 osd窗口0和video窗口0混合率
(0 << 2) | //TE0 osd窗口0透明,0=不使能,如果使能,根据
// BLND0出效果
(0 << 1) | //osd窗口0显示模式,0=Field,1=Frame
0; //osd窗口0激活=1
VPBE_OSD_OSDWIN1MD = 0 | 0 << 15 | //OASW window0的品质模式?
0 << 13 | //RGB1E RGB输入还是BITMAP输入
0 << 12 | //CLUTS1
0 << 10 | //OHZ1
0 << 8 | //OVZ1
0 << 6 | //BMW1
0 << 3 | //BLND1
0 << 2 | //TE1透明不使能
0 << 1 | //OFF1显示模式
0; //OACT1激活
//–
VPBE_OSD_RECTCUR = 0;
VPBE_OSD_BASEPX = basep_x;
VPBE_OSD_BASEPY = basep_y;
//video window0 参数选择--->> 4
VPBE_OSD_VIDWIN0OFST = width >> 4;
VPBE_OSD_VIDWIN0ADR = buffer; //video window0地址寄存器,这里指向DDR,最低5位忽略
VPBE_OSD_VIDWIN0XP = 0; //video window0 X起始坐标 实际偏移比此值少一半?
// 象素单位,从basepx开始算起,20刚好在边上
VPBE_OSD_VIDWIN0YP = 20; //此值对NTSC显示有影响,0则无影响
VPBE_OSD_VIDWIN0XL = width; //图象大小
VPBE_OSD_VIDWIN0YL = height >> 1; //video window0 Y轴(垂直)长度,以象素/行(pixels/lines)为单位
//在frame模式,根据line/field来指定值
//–其他参数
VPBE_OSD_MISCCTL = 0 //其他选择,比如Video window RGB 模式禁止了。
| (0 << 11) //video 窗口0、1延伸滤波器系数翻转,只有v1efc或v0efc
// 设置才有效,0=inversed,1=normal
| (0 << 9) // osd窗口0的REC601衰减使能,0=正常
| (0 << 8) // osd窗口1的REC601衰减使能,0=正常
| (0 << 7) //RGB使能=1,此时RGB数据会在内部转换成YUV422
| (0 << 6) //决定哪个video窗口用RGB模式0=window0,1=window1,(RGB888,24bit格式数据)
// 两个window不能同时用
| (0 << 4) //颜色查找表选择,0=表0,1=表1
| (0 << 2) //ping pong 缓冲翻转选择,
// 如果PPRV=0,0=VIDWIN0ADR地址,1=PPVWIN0ADR地址
// 如果PPRV=1,1=VIDWIN0ADR地址,0=PPVWIN0ADR地址
| (0 << 1) //ping pong 翻转选择PPRV
| 0; //reserved
//–video window0、1模式设置
VPBE_OSD_VIDWINMD = 0 //0x00000003; // video window1 模式设置
| (0 << 14) // video window1延伸滤波器凳,只有
// VVRSZ和EF位有效时才有效
| (0 << 12) // video window1 水平直接放大,0=1,1=2,2=4
| (0 << 10) // video window1 垂直直接放大
| (1 << 9) //video window1 显示模式 //手册是不是说错了?
//(1)如果为field模式,每field的line(在VIDWIN1YL指定),可以从
// 显示缓冲读取出来,而且每field数据可以重复的发送到VENC
//(2)如果为frame模式,2倍的line /field会从显示缓冲读取出来,而且
// 每field的数据隔行扫描到VENC
// 0=Field,1=Frame
| (0 << 8) //video 窗口1的图象是否显示,0=OFF
// ---以上为Video Window1参数,以下为Video Window0参数
//——video window0 模式设置—————
| (0 << 6) //类似14位
| (0 << 4) //类似12位
| (0 << 2) //类似10位
| (1 << 1) //类似9位
| (1 << 0); //类似8位
// 禁止 vwindow 1 and 使能 vwindow 0
// Frame 模式,with no up-scaling
/*
* Setup VENC
*/
if(ntsc_pal_mode == NTSC)
VPBE_VENC_VMOD = 0x00000003; // Standard NTSC interlaced output
else
VPBE_VENC_VMOD = 0 //0x00000043; // Standard PAL interlaced output
| (0 << 12) //VDMD数字图象输出模式0=YUV_p16bit,1=YUV_s8bit,2=RGB666_p18bit
| (0 << 11) //ITLCL非隔行扫描行号选择,0=262line(NTSC) 或 312 line(PAL)
// 1=263 line(NTSC) 或 313 line(PAL)
| (0 << 10) //ITLC 隔行扫描使能=0,当VMD=0和HDMD=0时有效
| (0 << 9) //NSIT非标准隔行扫描模式,当VMD=1时有效
// 0=逐行扫描,1=隔行扫描
| (0 << 8) //HDMD 高清模式=1,0=标准模式
| (1 << 6) //TVTYP,TV格式选择,当VMD=0时有效
// (1)HDMD=0,标准模式时,0=NTSC,1=PAL(代码默认)
// (2)HDMD=1,高清模式时,0=525P,1=625P
| (0 << 5) //SLAVE ,主从模式,0=master
| (0 << 4) //VMD,图象时序,0=NTSC/PAL 时序,1=非NTSC/PAL 时序
| (0 << 3) //BLNK,空白使能,同步信号和 色同步 仍然输出
// 0=normal,1=强迫blank
| (1 << 1) //VIE,复合模拟输出使能。0=固定Low-level输出
// 1=正常复合视频输出
| (1 << 0); //VENC,图象编码器使能
VPBE_VENC_VDPRO = 0 //colorbar_loopback_mode << 8; //图象数据处理寄存器0
| (0 << 14) //PFLTC 预滤波器C
| (0 << 12) //PFLTY 预滤波器Y
| (0 << 11) //PFLTR 预滤波器采样频率 0为enc/2
| (0 << 9) //CBTYP colorbar模式0=75%,1=100%
| (0 << 8) //colorbar使能 0=正常,1=COLORBARS *****************************
| (0 << 6) //ATRGB 输入图象RGB模式的薄化控制,取决REC601,0=禁止
| (0 << 5) //ATYCC 输入图象YCbCr模式的薄化控制,取决REC601,0=禁止
| (0 << 4) //ATCOM 输入图象复合模式的薄化控制,取决REC601,0=禁止
| (0 << 3) //DAFRQ DAC频率,0=27M,1=54M
| (0 << 2) //DAC x2过采样使能 0=off
| (0 << 1) //C信号过采样使能 0=off
| 0; //Y信号过采样使能 0=off
VPBE_VENC_DACTST = 0; //DAC测试寄存器,0为正常模式,1=省电(bit15 – bit12)
//
VPBE_VENC_DACSEL = 0x00004210;
// Choose Output mode
if(output_mode == COMPONENT_OUT)
VPBE_VENC_DACSEL = 0x00000000;
else if(output_mode == SVIDEO_OUT)
VPBE_VENC_DACSEL = 0x00004210;
}
//把图片变灰
void PictureGray(Uint32 memaddr)
{
Uint32 i = 0, tmp;
Uint8 yh, yl, cr, cb;
//注意Cb/Cr顺序
//由VPBE_OSD_MODE的15bit决定,0=cb/cr(set),1=cr/cb
// 刚好32位排列为Y-Cr-Y-Cb
for(i = 0; i < 345600; i++)
{
tmp = *(int *) memaddr;
yh = ((tmp >> 24) & 0xFF); //高Y
yl = ((tmp >> 8) & 0xFF);
cr = 0x80;
cb = 0x80;
tmp = (yh << 24) | (cr << 16) | (yl << 8) | cb;
*(int *) (memaddr) = tmp;
memaddr = memaddr + 4;
}
}
//
#define tvpaddr 0x5d
Int16 video_Color2gray()
{
Int16 ntsc_pal_mode;
Uint8 buff[4], getval = 0;
//先写这些:
/*
tvp5146_rset( 0xE8, 0x02 ); // Initalize TVP5146, must do after power on
tvp5146_rset( 0xE9, 0x00 ); // Skip if using TVP5146-M2
tvp5146_rset( 0xEA, 0x80 );
tvp5146_rset( 0xE0, 0x01 );
tvp5146_rset( 0xE8, 0x60 );
tvp5146_rset( 0xE9, 0x00 );
tvp5146_rset( 0xEA, 0xB0 );
tvp5146_rset( 0xE0, 0x01 );
tvp5146_rset( 0xE0, 0x00 );
tvp5146_rset( 0x03, 0x01 );
tvp5146_rset( 0x03, 0x00 ); */
//———测试tvp5146开始--------
//while(1){
//buff[0] = 0x80; //先指定一个地址,读取tvp5146的id=0x51
// getval = 1;
// getval = EVMDM6437_I2C_write(tvpaddr, buff, 1);
//
// buff[0] = 0;
// buff[1] = 0;
// getval = 1;
// getval = EVMDM6437_I2C_read(tvpaddr, buff, 2);
// getval++; //断点观察buff[0]=0x51,buff[1]=0x46
// }
//———测试tvp5146结束--------
ntsc_pal_mode = PAL; //NTSC;//自己加的
//tvp5146_init(ntsc_pal_mode, COMPONENT_IN); //复合视频模式,用VI_2_B
vpfe_init(0x81000000, 720, 480); // Setup Front-End
getval++; //
vpbe_init(0x81000000, 720, 480, LOOPBACK, ntsc_pal_mode, COMPONENT_OUT); // Setup Back-End
EVMDM6437_waitusec(1000000);
VPFE_CCDC_PCR = 0; //禁止输入
PictureGray(0x81000000); //断点1
return 0;
}
kooking:
根据你的程序vpfe_init() vpbe_init()和PictureGray()共用一个参数,就是内存的物理地址,所以将pfe_init() vpbe_init()改写成有返回值的,作为参数传给PictureGray(),应该就可以用在视频处理中了
no no5:
回复 kooking:
谢谢你的回答,你的意思是说,在vpfe_init() vpbe_init()这两个函数最后加个return buffer,然后把buffer 在PictureGray()中使用是吗?
kooking:
回复 no no5:
我没有细看程序的实现,但根据几个函数的调用关系,主要传递的应该就是那个buff的地址,你可以改成有返回值的,先测试图片,在测试视频的
no no5:
回复 kooking:
但是我BUFF的地址是固定的啊。不是变化的啊,而已BUFF地址不是放图像的像素点的吗?和它有关系吗?是不是有个叫ping pang buffer的?但是我不会用。能说说看 ?或者你还有什么另外的 想法?