我是菜鸟,做一个视频通信的软件.遇到调试不能过,是RGB转YUV处,请大家帮帮忙看看,谢谢。。。
从摄像头采集到视频数据-->编码-->传输->解码->播放;
在编码之前进行RGB-->YUV的转换,如下代码:
void CPTPHelpDlg::SendVideo(BYTE *data,int size)
{
CRect wndrect;
Bits bits; // Various count about compression
if(vidcap->isOver==TRUE)
return;
if(data==NULL)
return;
// Display the captured frame...
if(isViewLocalVideo)
{
::DrawDibDraw(hdib,
m_hdc,
local_wnd_x, // dest : left pos
local_wnd_y, // dest : top pos
IMAGE_WIDTH*1.5,//-1, // don't stretch
IMAGE_HEIGHT*1.5,//-1, // don't stretch
&m_bmpinfo->bmiHeader, // bmp header info
data, // bmp data
0, // src :left
0, // src :top
IMAGE_WIDTH, // src : width
IMAGE_HEIGHT, // src : height
DDF_SAME_DRAW // use prev params....
);
}
if(isVideoSend)
{
//log.WriteString("\n Converting to YUV format..");
//Convert the data from rgb format to YUV format
ConvertRGB2YUV(IMAGE_WIDTH,IMAGE_HEIGHT,data,yuv);
// Reset the counter
count=0;
//Compress the data...to h263
cparams.format=CPARAM_CIF;
cparams.inter = CPARAM_INTRA;
cparams.Q_intra = 8;
cparams.data=yuv; // Data in YUV format...
CompressFrame(&cparams, &bits);
// Transmit the compressed frame
//log.WriteString("Transmitting the frame");
dvideo.SendVideoData(cdata,count);
}
}
// Conversion from RGB to YUV420
int RGB2YUV_YR[256], RGB2YUV_YG[256], RGB2YUV_YB[256];
int RGB2YUV_UR[256], RGB2YUV_UG[256], RGB2YUV_UBVR[256];
int RGB2YUV_VG[256], RGB2YUV_VB[256];
void InitLookupTable()
{
int i;
for (i = 0; i < 256; i++) RGB2YUV_YR[i] = (float)65.481 * (i<<8);
for (i = 0; i < 256; i++) RGB2YUV_YG[i] = (float)128.553 * (i<<8);
for (i = 0; i < 256; i++) RGB2YUV_YB[i] = (float)24.966 * (i<<8);
for (i = 0; i < 256; i++) RGB2YUV_UR[i] = (float)37.797 * (i<<8);
for (i = 0; i < 256; i++) RGB2YUV_UG[i] = (float)74.203 * (i<<8);
for (i = 0; i < 256; i++) RGB2YUV_VG[i] = (float)93.786 * (i<<8);
for (i = 0; i < 256; i++) RGB2YUV_VB[i] = (float)18.214 * (i<<8);
for (i = 0; i < 256; i++) RGB2YUV_UBVR[i] = (float)112 * (i<<8);
}
//
// Convert from RGB24 to YUV420
//
int ConvertRGB2YUV(int w,int h,unsigned char *bmp,unsigned int *yuv)
{
unsigned int *u,*v,*y,*uu,*vv;
unsigned int *pu1,*pu2,*pu3,*pu4;
unsigned int *pv1,*pv2,*pv3,*pv4;
unsigned char *r,*g,*b;
int i,j;
uu=new unsigned int[w*h];
vv=new unsigned int[w*h];
if(uu==NULL || vv==NULL)
return 0;
y=yuv;
u=uu;
v=vv;
// Get r,g,b pointers from bmp image data....
r=bmp;
g=bmp+1;
b=bmp+2;
//Get YUV values for rgb values...
for(i=0;i<h;i++)
{
for(j=0;j<w;j++)
{
*y++=( RGB2YUV_YR[*r] +RGB2YUV_YG[*g]+RGB2YUV_YB[*b]+1048576)>>16;
*u++=(-RGB2YUV_UR[*r] -RGB2YUV_UG[*g]+RGB2YUV_UBVR[*b]+8388608)>>16;
*v++=( RGB2YUV_UBVR[*r]-RGB2YUV_VG[*g]-RGB2YUV_VB[*b]+8388608)>>16;
r+=3;
g+=3;
b+=3;
}
}
在红色函数出错,调试出现access violate这样的错误。
不知道是不是data指针传到RGB2YUV函数的形参char*bmp时出错,因为调试最后停在了
*y++=( RGB2YUV_YR[*r] +RGB2YUV_YG[*g]+RGB2YUV_YB[*b]+1048576)>>16;处,应该是RGB2YUV_YR[*r]这个值得不到。。。。
我知道的就这么多,我是一个菜鸟,请大家多多指教啊,,,
不是参数转换出错,是访问数组越界。 bmp 这个缓冲区的大小可能没有3*w*h 这么大,你打开VC 的 调试窗口,看 bmp 指向的 memory ,看看到多少就有问题。
还有yuv 这个缓冲区,代码中没有声明,不知道是怎样的一个缓冲,也有可能是这个缓冲区访问越界。
你可以打印 *y , *u, *v, *r, *g, *b 这些值,看出错时这些值为多少,然后再到 memory 窗口中看对应的地址是否可以访问。
从你的补充来看,应该是 bmp 指定的默认缓冲区大小没有你想象的 3*w*h 那么大,是不是vfw分辨率设置问题,实际传过来的没那么大。