首页 新闻 会员 周边

视频通信问题

0
悬赏园豆:200 [已解决问题] 解决于 2010-06-01 08:56

我是菜鸟,做一个视频通信的软件.遇到调试不能过,是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]这个值得不到。。。。

我知道的就这么多,我是一个菜鸟,请大家多多指教啊,,,

问题补充: 首先十分感谢eaglet。 单步 调试出错时i=193,j=328,*r是expression cannot evaluate.我设置了w*h=352*288; bmp指针是从vfw采集缓冲传过来的,他的大小都是按默认的...我在本地显示视频没问题,YUV定义应该没错: unsigned int yuv[ CIF_WIDTH*CIF_HEIGHT + (CIF_WIDTH*CIF_HEIGHT)/2 ]; 我还是不知道怎么弄,可否再指导下啊,。。或留个QQ,谢谢哈~~ 会是摄像头采集到的格式就是YUV了吗?怎么判断视频格式...我的摄像头没有说明书 我看了,那个缓冲区大小是W*H*2,是不是表明采集到的是YUV422的啊?
飞鸟...的主页 飞鸟... | 初学一级 | 园豆:0
提问于:2010-05-17 20:09
< >
分享
最佳答案
0

不是参数转换出错,是访问数组越界。 bmp 这个缓冲区的大小可能没有3*w*h 这么大,你打开VC 的 调试窗口,看 bmp 指向的 memory ,看看到多少就有问题。

还有yuv 这个缓冲区,代码中没有声明,不知道是怎样的一个缓冲,也有可能是这个缓冲区访问越界。

你可以打印 *y , *u, *v, *r, *g, *b 这些值,看出错时这些值为多少,然后再到 memory 窗口中看对应的地址是否可以访问。

从你的补充来看,应该是 bmp 指定的默认缓冲区大小没有你想象的 3*w*h 那么大,是不是vfw分辨率设置问题,实际传过来的没那么大。

收获园豆:200
eaglet | 专家六级 |园豆:17139 | 2010-05-18 07:33
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册