windows mobile視訊通話開發記錄

來源:互聯網
上載者:User
系統架構(暫時不處理語音通話部分):

擷取網路攝影機資料-->編碼-->傳輸->解碼->播放

1.擷取網路攝影機資料
通過DShow已經可以得到16RGB或者24RGB(略)

2.轉化資料到YUV420
// 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;
}

}

這是網上流傳的經典的轉碼,按理應該沒錯,但是起初用的時候根本無法正確轉換,後來將unsigned int全部改為unsigned char,可以轉換,但是映像是倒立的,並且顏色偏綠,之所以說經典是效率高。

下面看另一種轉換:

void ReadBmp(unsigned char *RGB,FILE *fp)//便於調試用本地圖片載入資料
{
int i,j;
unsigned char temp;

fseek(fp,54, SEEK_SET);

fread(RGB+WIDTH*HEIGHT*3, 1, WIDTH*HEIGHT*3, fp);//讀取
for(i=HEIGHT-1,j=0; i>=0; i--,j++)//調整順序
{
memcpy(RGB+j*WIDTH*3,RGB+WIDTH*HEIGHT*3+i*WIDTH*3,WIDTH*3);
}
//這裡做了順序調整,所以出來的圖片是正常的方向,可見第一種方法沒有進行資料順序轉換
//順序調整
for(i=0; (unsigned int)i < WIDTH*HEIGHT*3; i+=3)
{
temp = RGB[i];
RGB[i] = RGB[i+2];
RGB[i+2] = temp;
}
}

void Convert(unsigned char *RGB, unsigned char *YUV)
{
//變數聲明
unsigned int i,x,y,j;
unsigned char *Y = NULL;
unsigned char *U = NULL;
unsigned char *V = NULL;

Y = YUV;
U = YUV + WIDTH*HEIGHT;
V = U + ((WIDTH*HEIGHT)>>2);

for(y=0; y < HEIGHT; y++)
for(x=0; x < WIDTH; x++)
{
j = y*WIDTH + x;
i = j*3;
Y[j] = (unsigned char)(DY(RGB[i], RGB[i+1], RGB[i+2]));

if(x%2 == 1 && y%2 == 1)
{
j = (WIDTH>>1) * (y>>1) + (x>>1);
//上面i仍有效
U[j] = (unsigned char)
((DU(RGB[i  ], RGB[i+1], RGB[i+2]) +
DU(RGB[i-3], RGB[i-2], RGB[i-1]) +
DU(RGB[i  -WIDTH*3], RGB[i+1-WIDTH*3], RGB[i+2-WIDTH*3]) +
DU(RGB[i-3-WIDTH*3], RGB[i-2-WIDTH*3], RGB[i-1-WIDTH*3]))/4);

V[j] = (unsigned char)
((DV(RGB[i  ], RGB[i+1], RGB[i+2]) +
DV(RGB[i-3], RGB[i-2], RGB[i-1]) +
DV(RGB[i  -WIDTH*3], RGB[i+1-WIDTH*3], RGB[i+2-WIDTH*3]) +
DV(RGB[i-3-WIDTH*3], RGB[i-2-WIDTH*3], RGB[i-1-WIDTH*3]))/4);
}

}
}

第二種方法OK,轉換成YUV420以後和原先的BMP對照,肉眼幾乎分辨不出有什麼失真。但是……效率太低下了。兩種轉換在相同的模擬器上跑,第一種大約是320--350ms,而第二種竟然達到了驚人的6000Ms.
效果對比圖:

第二種(不失真,效率低)                                  第一種(失真,效率高)

接下來的時間,儘快解決第一種轉換方法的偏差。

OK~沒想到就用了幾分鐘調整了順序,第一種方法就搞定,貌似顯示的效果比第二種佳。
看圖:

11.13
預覽和視頻捕獲能支援144X176  120X160   240X320
圖片拍攝就只能240X320   480X640
then,

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.