VFW采集免驱动USB摄相头的视频,
biCompression = 844715353, 在网上看资料介绍是YUY2格式,也就是YUV422用下面的代码转换后,发送出去;
传入的参数是VFW采集的原始视频流。接收端接受到,转成RGB24进行播放,但是视频很模糊。
不清楚什么原因int YUV422To420(unsigned char *pYUV, unsigned int *yuv, int lWidth, int lHeight)
{        
int i,j;
unsigned int *pY = yuv;
unsigned int *pU = yuv + lWidth*lHeight;
unsigned int *pV = pU + (lWidth*lHeight)/4;unsigned char *pYUVTemp = pYUV;
unsigned char *pYUVTempNext = pYUV+lWidth*2;
        
 for(i=0; i<lHeight; i+=2)
 {
    for(j=0; j<lWidth; j+=2)
     {
       pY[j] = *pYUVTemp++;
       pY[j+lWidth] = *pYUVTempNext++;
                        
       pU[j/2] =(*(pYUVTemp) + *(pYUVTempNext))/2;
       pYUVTemp++;
       pYUVTempNext++;
                        
       pY[j+1] = *pYUVTemp++;
       pY[j+1+lWidth] = *pYUVTempNext++;
                        
       pV[j/2] =(*(pYUVTemp) + *(pYUVTempNext))/2;
       pYUVTemp++;
       pYUVTempNext++;
     }
       pYUVTemp+=lWidth*2;
       pYUVTempNext+=lWidth*2;
       pY+=lWidth*2;
       pU+=lWidth/2;
       pV+=lWidth/2;
   }
        
       return 1;
}

解决方案 »

  1.   

    如果是转换不对的话 应该是视频花屏或者色彩不对。或者视频只有半截。你现在仅仅是视频模糊。可以尝试在转换以后,将码流保存。CSDN下载里面有yuv viewer。直接用那个播放。先不管发送那部分的代码。然后看下问题。
      

  2.   

    biCompression = 844715353
    biBitCount = 16
    看网上介绍说是 YUY2格式, 我也不是很确定.
      

  3.   

    void YUV422To420(unsigned char* pYUV, 
    unsigned char* pY, unsigned char* pU, unsigned char* pV, 
    int lWidth, int lHeight)之前看别的程序, 有的多传入三个参数
    unsigned char* pY, unsigned char* pU, unsigned char* pV, 
    不知道这个是否有影响...
      

  4.   

    找个关系不大,你的函数 是结果保存到了yuv一维数组中。
      

  5.   

    视频的原始数据,  是VFW采集视频时,在回调函数中获取的.
      

  6.   

    你首先要确定数据是分片数据还是打包数据,常说的YUY2指YUYV,采样信号是Y:U:V=4:2:2,YUV422数据常指分片数据,即和YUV420一样,Y一片,U一片,V一片看你的代码,实质是打包的YUYV转为分片的YUV420,这种情况下,YUV420的UV的高将变为YUYV中UV高的一半
    算法实现上,Y不变化,纯属拷贝
    至于UV,算法一样,即YUYV的奇场和偶场分别进行插值按序产生YUV420中UV的一行,而不是你代码中的奇行和偶行进行平均插值
    另外,看你UV插值算法中使用的是平均插值,也可以修改,奇场使用3:1插值,偶场使用1:3插值,即对称计算
      

  7.   


    int YUV422To420(unsigned char *pYUV, unsigned int *yuv, int lWidth, int lHeight)
    {        
    int i,j;
    unsigned int *pY = yuv;
    unsigned int *pU = yuv + lWidth*lHeight;
    unsigned int *pV = pU + (lWidth*lHeight)/4;unsigned char *pYUVTemp = pYUV;
    unsigned char *pYUVTempNext = pYUV+lWidth*2;
    unsigned char *pYUV2 = pYUVTempNext + lWidth*2;
    unsigned char *pYUV3 = pYUVTempNext + lWidth*4;
            
     for(i=0; i<lHeight; i+=4)
     {
        for(j=0; j<lWidth; j+=4)
         {
             // Y0
             pY[j] = *pYUVTemp++;
             pY[j+lWidth] = *pYUVTempNext++;
             pY[j+lWidth*2] = *pYUV2++;
             pY[j+lWidth*3] = *pYUV3++;
             // U
             pU[j/2] = (3*pYUVTemp[j] + pYUV2[j])/4;
             pU[j/2+lWidth/2] = (pYUVTempNext[j] + 3*pYUV3[j])/4;
             // Y1
             pY[j+1] = *pYUVTemp++;
             pY[j+lWidth+1] = *pYUVTempNext++;
             pY[j+lWidth*2+1] = *pYUV2++;
             pY[j+lWidth*3+1] = *pYUV3++;
             // V
             pV[j/2] = (3*pYUVTemp[j] + pYUV2[j])/4;
             pV[j/2+lWidth/2] = (pYUVTempNext[j] + 3*pYUV3[j])/4;     }
           pYUVTemp+=lWidth*2*4;
           pYUVTempNext+=lWidth*2*4;
           pYUV2+=lWidth*2*4;
           pYUV3+=lWidth*2*4;
           pY+=lWidth*4;
           pU+=lWidth;
           pV+=lWidth;
       }
            
           return 1;
    }
      

  8.   

    ======================for(i=0; i<lHeight; i+=4)
    {
     for(j=0; j<lWidth; j+=4)
     {
      // Y0
      pY[j] = *pYUVTemp++;
      pY[j+lWidth] = *pYUVTempNext++;
      pY[j+lWidth*2] = *pYUV2++;
      pY[j+lWidth*3] = *pYUV3++; //执行到该行代码,出现异常//获取摄相头原始视频的相关参数
    capGetVideoFormat(m_capwnd,&m_bmpinfo,sizeof(m_bmpinfo));m_bmpinfo.bmiHeader.biSize   =40
    m_bmpinfo.bmiHeader.biWidth   =176
    m_bmpinfo.bmiHeader.biHeight   =144
    m_bmpinfo.bmiHeader.biPlanes   =1
    m_bmpinfo.bmiHeader.biBitCount   =16
    m_bmpinfo.bmiHeader.biCompression =844715353
    m_bmpinfo.bmiHeader.biSizeImage   =50688
      

  9.   

    大意了,每四行计算时,牵引错误,试试下面的代码吧,不过这种代码很有优化的余地
    书籍可以参考“视频技术手册”,上面有YUV422到YUV420采样转换的讲解int YUV422To420(unsigned char *pYUV, unsigned int *yuv, int lWidth, int lHeight)
    {        
    int i,j;
    unsigned int *pY = yuv;
    unsigned int *pU = yuv + lWidth*lHeight;
    unsigned int *pV = pU + (lWidth*lHeight)/4;unsigned char *pYUVTemp = pYUV;
    unsigned char *pYUVTempNext = pYUV+lWidth*2;
    unsigned char *pYUV2 = pYUVTempNext + lWidth*2;
    unsigned char *pYUV3 = pYUVTempNext + lWidth*4;
            
     for(i=0; i<lHeight; i+=4)
     {
        for(j=0; j<lWidth; j+=4)
         {
             // Y0
             pY[j] = pYUVTemp[j];
             pY[j+lWidth] = pYUVTempNext[j];
             pY[j+lWidth*2] = pYUV2[j];
             pY[j+lWidth*3] = pYUV3[j];
             // U
             pU[j/2] = (3*pYUVTemp[j+1] + pYUV2[j+1])/4;
             pU[j/2+lWidth/2] = (pYUVTempNext[j+1] + 3*pYUV3[j+1])/4;
             // Y1
             pY[j+1] = pYUVTemp[j+2];
             pY[j+lWidth+1] = pYUVTempNext[j+2];
             pY[j+lWidth*2+1] = pYUV2[j+2];
             pY[j+lWidth*3+1] = pYUV3[j+2];
             // V
             pV[j/2] = (3*pYUVTemp[j+3] + pYUV2[j+3])/4;
             pV[j/2+lWidth/2] = (pYUVTempNext[j+3] + 3*pYUV3[j+3])/4;     }
           // 分别加四行
           pYUVTemp+=lWidth*2*4;
           pYUVTempNext+=lWidth*2*4;
           pYUV2+=lWidth*2*4;
           pYUV3+=lWidth*2*4;
          // Y加上四行
           pY+=lWidth*4;
            // UV加两行
           pU+=lWidth;
           pV+=lWidth;
       }
            
           return 1;
    }
      

  10.   

    biBitCount = 16 ????"接收端接受到,转成RGB24进行播放,但是视频很模糊。"
    RGB24 的 biBitCount = 24 ????去我的资源看看吧,也许有你需要的东西。
      

  11.   

    ===================
    好象有驱动的,一般都是24位, RGB24
    免驱动的一般都是16位, 大概是 YUY2
      

  12.   

    下面均指每通道8bit,即量化除数为256,值为0~255
    YUYV/UYVY,每个像素16bit,因为第二个UV丢弃
    RGBA,每个像素32bit
    RGB/BGR,每个像素24Bit
    YUV422/YUV420/YUV411,分片数据,Y一片,U一片,V一片
    可查询微软MSDN,或者参考《视频技术手册》
      

  13.   

    =======================
    YUY2是免驱动USB摄相头,采集的原始视频,
    具体是分片,还是打包方式,还不是太清楚.biCompression = 844715353
    biBitCount = 16
    看网上介绍说是 YUY2格式, 我也不是很确定.通过VFW的API来设置biBitCount = 24, 但是设置不成功.
      

  14.   

    YUY2即YUYV,是打包方式
    排列即为Y0 U0 Y1 V0 Y2 U2 Y3 V2 Y4 U4 Y5 V4...
    注意到,Y是没有丢弃的,但是U和V丢弃了偶数列像素(索引从0开始,即丢弃了U1,V1,U3,V3...)
      

  15.   

    最近又碰到一个很奇怪的问题:
    用C++封装DLL来采集视频,通过回调函数传给C#,
    然后让C#来播放;RGB格式的播放没有问题,但是YUY2格式的播放的时候,屏幕总是闪烁,
    一会清晰,一会绿屏,感觉数据有问题。不知道是C#不能直接播放YUY2数据,还是因为通过回调函数回发数据的速度太快了。在C#版块发的一个帖子C# 是否可以播放YUY2格式的视频?
    http://topic.csdn.net/u/20110706/17/6b6fe826-4d28-4d6c-bb0e-0abc8db15c08.html