局域網(wǎng)聊天室系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)_第1頁(yè)
局域網(wǎng)聊天室系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)_第2頁(yè)
局域網(wǎng)聊天室系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)_第3頁(yè)
局域網(wǎng)聊天室系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)_第4頁(yè)
局域網(wǎng)聊天室系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)_第5頁(yè)
已閱讀5頁(yè),還剩23頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

PAGE第1頁(yè)共1頁(yè)畢業(yè)論文局域網(wǎng)聊天室系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)論文作者姓名:申請(qǐng)學(xué)位專業(yè):申請(qǐng)學(xué)位類別:論文提交日期:基于局域網(wǎng)的視頻聊天室系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)摘要視頻聊天系統(tǒng)作為一種新型的通信和交流工具,突破了地域的限制,可以提供更為便捷、靈活、全面的音、視頻信息的傳遞和服務(wù),具有極其廣泛的發(fā)展前景。本文介紹了采用JAVA編程開發(fā)視頻聊天系統(tǒng)的一套比較常用的解決方案。文字聊天采用TCP模式;語(yǔ)音視頻聊天采用UDP模式,在客戶端之間點(diǎn)對(duì)點(diǎn)的進(jìn)行。在該方案中,通過函數(shù)庫(kù)VFW來(lái)實(shí)現(xiàn)視頻捕獲、影像壓縮以及影像播放。微軟公司提供的專門用于視頻捕獲開發(fā)的工具包VFW,為在Windows操作系統(tǒng)中實(shí)現(xiàn)視頻捕獲提供了標(biāo)準(zhǔn)的接口,從而大大降低了程序的開發(fā)難度。在視頻傳輸方面,則通過組建視頻幀,將位圖形式的視頻幀壓縮成幀格式的Mpeg4流,傳輸?shù)娇蛻舳撕?,解壓并顯示影像。同時(shí),在本方案中,采用了線程來(lái)實(shí)現(xiàn)語(yǔ)音錄制和語(yǔ)音回放,最終實(shí)現(xiàn)了通過服務(wù)器中轉(zhuǎn)的文字聊天、點(diǎn)對(duì)點(diǎn)的語(yǔ)音視頻聊天。關(guān)鍵詞:文字聊天;VFW;視頻捕獲;視頻傳輸;語(yǔ)音錄制;語(yǔ)音回放TheDesignandRealizationofLAN-BasedVideoChatRoomSystemAbstractAsanewtoolaboutcommunication,videochattingsystemhasbrokenthroughgeographicalrestrictions,hasprovidesmoreconvenient,flexibleandcompletetransmissionandservice.Furthermore,ithasaverybrightfuture.ThecommonsolutionabouthowtodevelopavideochattingsystemisintroducedbytheMicrosoftVisualC++6.0programming.TCPmodelisusedinthetextchattingandUDPforthepoint-to-pointvideochatsbetweentheClients.Inthisplan,VideoCapture,VideoCompressionManagerandDrawDibarerealizedbythefunctionsofVFWLibrary.ThespecialkitVFW(VideoforWindows)invideocaptureofferedbyMicrosoftCorporation,hasprovidedastandardinterfaceforvideocaptureinWindowsOperatingSystemandthusgreatlyreducedthehardshipofprogramming.Invideotransmissionaspect,itrequiresavideoframewhichiscompressedthevideoframeofbitmapintoMpeg4steamofframeform.ThenitwillbedecompressedintoimagessinceithasbeenarrivedtheClient.Meanwhile,thethreadisusedtoachieveaudiorecordingandreplaying.Finally,ithasrealizedthetextchattingthroughaservertotransit,thepoint-to-pointaudioandvideochats.Keywords:textchatting;VFW;VideoCapture;videotransmission;audiorecording;audioplaying目錄論文總頁(yè)數(shù):24頁(yè)1 引言 11.1 課題背景 11.2 國(guó)內(nèi)外研究現(xiàn)狀 12 理論知識(shí)介紹 12.1 VFW簡(jiǎn)介 12.2 線程的實(shí)現(xiàn)方法 43 需求分析 53.1 軟硬件環(huán)境 53.2 需求分析 54 系統(tǒng)結(jié)構(gòu) 74.1 硬件結(jié)構(gòu) 74.2 軟件結(jié)構(gòu) 74.2.1 功能需求 74.2.2 系統(tǒng)功能模塊圖 84.3 系統(tǒng)各模塊流程圖 85 系統(tǒng)的詳細(xì)設(shè)計(jì) 105.1 文字聊天 105.1.1 TCP套接字的運(yùn)用 105.1.2 文字聊天實(shí)現(xiàn) 115.2 語(yǔ)音視頻聊天 135.2.1 UDP套接字的運(yùn)用 135.2.2 視頻的捕獲 145.2.3 捕獲窗口 165.2.4 視頻捕獲驅(qū)動(dòng) 185.2.5 語(yǔ)音錄制 185.2.6 語(yǔ)音回放 195.2.7 視音頻的傳輸 20結(jié)論 21參考文獻(xiàn) 22致謝 23聲明 24第24頁(yè)共24頁(yè)引言課題背景隨著Internet的不斷發(fā)展普及,網(wǎng)絡(luò)通訊越來(lái)越被千家萬(wàn)戶所接受,成為人們生活中的一部分。網(wǎng)絡(luò)聊天已和手機(jī)等一樣,成為人們運(yùn)用最為廣泛的通信工具之一。本畢業(yè)設(shè)計(jì)的目的主要是為了滿足人們通訊交流的便捷,實(shí)現(xiàn)靈活、全面的音、視頻信息的傳遞和服務(wù)。模擬騰訊公司的QQ聊天軟件,開發(fā)一個(gè)多功能的聊天系統(tǒng)軟件,本畢業(yè)設(shè)計(jì)主要實(shí)現(xiàn)視頻語(yǔ)音聊天、文字聊天等功能。國(guó)內(nèi)外研究現(xiàn)狀隨著網(wǎng)絡(luò)寬帶業(yè)務(wù)的推廣與普及,加之視頻產(chǎn)品設(shè)備(如攝像頭、耳機(jī)、麥克風(fēng)等)的成熟,普通用戶可以輕松地借助網(wǎng)絡(luò)視頻通訊軟件,實(shí)現(xiàn)“面對(duì)面”的網(wǎng)絡(luò)交流。信息的無(wú)限量擴(kuò)大,交通工具的便捷,視頻技術(shù)的充分應(yīng)用等導(dǎo)致了行業(yè)間競(jìng)爭(zhēng)的全球化,這就要求現(xiàn)代部門、企業(yè)要具備更加靈敏的神經(jīng),更扁平化的管理,更快速的反應(yīng)和決策,更貼切的市場(chǎng)宣傳和服務(wù)。所有這一切是由信息技術(shù)的發(fā)展所帶來(lái)的,同樣也要求有先進(jìn)的信息技術(shù)來(lái)提高部門、企業(yè)的競(jìng)爭(zhēng)力?,F(xiàn)代通訊已經(jīng)是越來(lái)越普及了,必須有效合理的運(yùn)用視頻產(chǎn)品類設(shè)備來(lái)提高信息的傳遞和交流。在同一個(gè)局域網(wǎng)中,充分、合理的運(yùn)用攝像頭、耳機(jī)、麥克風(fēng)等設(shè)備來(lái)實(shí)現(xiàn)文字聊天和語(yǔ)音視頻聊天更是我們生活、學(xué)習(xí)、工作的便利所在。理論知識(shí)介紹VFW簡(jiǎn)介VFW是Microsoft1992年推出的關(guān)于數(shù)字視頻的一個(gè)軟件包,它能使應(yīng)用程序數(shù)字化并播放從傳統(tǒng)模擬視頻源得到的視頻剪輯。VFW的一個(gè)關(guān)鍵思想是播放時(shí)不需要專用硬件,為了解決數(shù)字視頻數(shù)據(jù)量大的問題,需要對(duì)數(shù)據(jù)進(jìn)行壓縮。它引進(jìn)了一種叫AVI的文件標(biāo)準(zhǔn),該標(biāo)準(zhǔn)未規(guī)定如何對(duì)視頻進(jìn)行捕獲、壓縮及播放,僅規(guī)定視頻和音頻該如何存儲(chǔ)在硬盤上,以及在AVI文件中交替存儲(chǔ)視頻幀和與之相匹配的音頻數(shù)據(jù)。VFW給程序員提供VBX和AVICap窗口類的高級(jí)編程工具,使程序員能通過發(fā)送消息或設(shè)置屬性來(lái)捕獲、播放和編輯視頻剪輯。用戶不必專門安裝VFW,在安裝Windows時(shí),安裝程序會(huì)自動(dòng)地安裝配置視頻所需的組件,如設(shè)備驅(qū)動(dòng)程序、視頻壓縮程序等。VFW主要由以下六個(gè)模塊組成:AVICAP.DLL:包含了執(zhí)行視頻捕獲的函數(shù),它給AVI文件、I/O和視頻音頻設(shè)備驅(qū)動(dòng)程序提供一個(gè)高級(jí)接口;MSVIDEO.DLL:用一套特殊的DrawDib函數(shù)來(lái)處理屏幕上的視頻操作;MCIAVI.DRV:此驅(qū)動(dòng)程序包括對(duì)VFW的MCI命令的解釋器;AVIFILE.DLL:支持由標(biāo)準(zhǔn)多媒體I/O(mmio)函數(shù)提供的更高的命令來(lái)訪問AVI文件;壓縮管理器(ICM):管理用于視頻壓縮/解壓縮的編解碼器(CODEC);音頻壓縮管理器ACM:提供與ICM相似的服務(wù),不同的是它適于波形音頻。VisualC++在支持VFW方面提供有vfw32.lib、msacm32.lib、winmm.lib等庫(kù)。特別是它提供了功能強(qiáng)大、簡(jiǎn)單易行、類似于MCIWnd的窗口類AVICap。AVICap為應(yīng)用程序提供了一個(gè)簡(jiǎn)單的、基于消息的接口,使之能訪問視頻和波形音頻硬件,并能在將視頻流捕獲到硬盤上的過程中進(jìn)行控制。AVICap支持實(shí)時(shí)的視頻流捕獲和單幀捕獲,并提供對(duì)視頻源的控制。雖然MCI也提供數(shù)字視頻服務(wù),比如,它為顯示AVI文件的視頻提供了AVIVideo命令集,為視頻疊加提供了overlay命令集,但這些命令主要是基于文件的操作,不能滿足實(shí)時(shí)地直接從視頻緩存中獲取數(shù)據(jù)的要求。對(duì)于使用沒有視頻疊加能力的捕獲卡的PC機(jī)來(lái)說,用MCI提供的命令集是無(wú)法捕獲視頻流的。而AVICap在捕獲視頻方面具有一定的優(yōu)勢(shì),它能直接訪問視頻緩沖區(qū),不需要生成中間文件,實(shí)時(shí)性很強(qiáng),效率很高。同時(shí),它也可將數(shù)字視頻捕獲到文件。在視頻捕獲之前需要?jiǎng)?chuàng)建一個(gè)捕獲窗,所有的捕獲操作及其設(shè)置都以它為基礎(chǔ)。用AVICap窗口類創(chuàng)建的窗口(通過capCreateCaptureWindow函數(shù)創(chuàng)建)被稱為“捕獲窗”,其窗口風(fēng)格一般為WS_CHILD和WS_VISIBLE。實(shí)際上,捕獲窗類似于標(biāo)準(zhǔn)控制(如按鈕、列表框等)。捕獲窗具有下列功能:將視頻流和音頻流捕獲到一個(gè)AVI文件中;動(dòng)態(tài)地同視頻和音頻輸入器件連接或斷開;以O(shè)verlay或Preview模式對(duì)輸入的視頻流進(jìn)行實(shí)時(shí)顯示;在捕獲時(shí)可指定所用的文件名并能將捕獲文件的內(nèi)容拷貝到另一個(gè)文件;設(shè)置捕獲速率;顯示控制視頻源、視頻格式、視頻壓縮的對(duì)話框;創(chuàng)建、保存或載入調(diào)色板;將圖像和相關(guān)的調(diào)色板拷貝到剪貼板;將捕獲的一個(gè)單幀圖像保存為DIB格式的文件。AVICap在顯示視頻時(shí)提供的兩種模式:(A)預(yù)覽(Preview)模式:該模式使用CPU資源,視頻幀先從捕獲硬件傳到系統(tǒng)內(nèi)存,接著采用GDI函數(shù)在捕獲窗中顯示。在物理上,這種模式需要通過VGA卡在監(jiān)視器上顯示。(B)疊加(Overlay)模式:該模式使用硬件疊加進(jìn)行視頻顯示,疊加視頻的顯示不經(jīng)過VGA卡,疊加視頻的硬件將VGA的輸出信號(hào)與其自身的輸出信號(hào)合并,形成組合信號(hào)顯示在計(jì)算機(jī)的監(jiān)視器上。只有部分視頻捕獲卡才具有視頻疊加能力。靈活編寫AVICap提供的回調(diào)函數(shù)還可滿足一些特殊需求。比如,將宏capCaptureSequenceNoFile同用capSetCallbackOnVideoStream登記的回調(diào)函數(shù)一起使用,可使應(yīng)用程序直接使用視頻和音頻數(shù)據(jù)。在視頻聊天的應(yīng)用程序中可利用這一點(diǎn)來(lái)獲得視頻幀,回調(diào)函數(shù)將捕獲的圖像傳到遠(yuǎn)端的計(jì)算機(jī)。應(yīng)用程序可用捕獲窗來(lái)登記回調(diào)函數(shù)(由用戶編寫,而由系統(tǒng)調(diào)用),以便在發(fā)生下列情況時(shí),它能通知應(yīng)用程序,作出相應(yīng)的反應(yīng):捕獲窗狀態(tài)改變;出錯(cuò);視頻幀和音頻緩存可以使用;在捕獲過程中,其它應(yīng)用程序處于讓步(Yield)地位。視頻捕獲編程也要用到涉及視頻捕獲的結(jié)構(gòu)、宏、消息和函數(shù)。令人高興的是,發(fā)送AVICap窗口消息所能完成的功能都能調(diào)用相應(yīng)的宏來(lái)完成。例如,SendMessage(hWndCap,WM_CAP_DRIVER_CONNECT,0,0L)與capDriverConnect(hWndCap,0)的作用相同,都是將創(chuàng)建的捕獲窗同視頻輸入器件連接起來(lái)。視頻部分主要是利用VideoCapture函數(shù)庫(kù)來(lái)獲取影像的。VideoCapture主要提供下列功能:連接驅(qū)動(dòng)程序;獲取影像、聲音資料,并顯示在屏幕上或者是存成AVI文件;獲取單張影像顯示在屏幕上,拷貝至剪貼簿,或者是存成DIB(Device-IndependentBitmap)文件。VideoCapture的主要結(jié)構(gòu):結(jié)構(gòu)體CAPTUREPARAMS主要包含一些獲取圖像的參數(shù):DWORDdwRequestMicroSecPerFrame代表相鄰兩個(gè)frame的獲取時(shí)間間隔;BOOLfYield值為TRUE,則表示W(wǎng)indows會(huì)以另一個(gè)thread來(lái)捕獲影像,值為FALSE,程序會(huì)在捕捉影像后顯示忙碌狀態(tài);BOOLfCaptureAudio其值表示是否需要同時(shí)獲取聲音資料。結(jié)構(gòu)體BITMAPINFO和點(diǎn)陣圖有關(guān),主要定義了影像獲取之后顯示在屏幕上、存儲(chǔ)在文件中的格式,它包含兩個(gè)成員:BITMAPINFOHEADERbmiHeader描述影像性質(zhì)的結(jié)構(gòu),其成員記載了影像的大小、顏色深度和壓縮的方式,該成員在VideoCapture、VideoCompressionManager和DrawDib函數(shù)庫(kù)中,以及有關(guān)于點(diǎn)陣圖的應(yīng)用中;RGBQUADbmiColors指向colortable第一個(gè)元素的位置。結(jié)構(gòu)體COMPVARS主要是記錄所有和壓縮相關(guān)的信息,重要的成員:DWORDfccHandler為compressor句柄;LPBITMAPINFOlpbiIn指向待壓縮影像BITMAPINFO的指標(biāo);LPBITMAPINFOlpbitOut:指向壓縮完影像BITMAPINFO的指標(biāo);LONGlKey代表key-framerate,而所謂keyframe是指此frame在解壓縮時(shí)不需要依賴前面的frame;LONGlQ代表影像壓縮后的品質(zhì),取值為1~10000的整數(shù)。VideoCompressionFunctions主要記錄壓縮功能相關(guān)的信息,其包含的比較重要的成員:ICLocate輸入指向壓縮前后BITMAPINFO的指標(biāo),以及欲使用的codecs;ICCompressorChoose呼叫一個(gè)系統(tǒng)內(nèi)建的對(duì)話,其中包含所有可能使用的codes以及其相關(guān)參數(shù);ICCompressQuery詢問compressor是否支持某種壓縮方式,輸入?yún)?shù)為compressorhandle及指向壓縮前后BITMAPINFO的指標(biāo),此函數(shù)會(huì)傳回詢問結(jié)果;ICCompressBegin要求系統(tǒng)準(zhǔn)備相關(guān)資源以供壓縮之用;ICCompress壓縮某個(gè)frame;ICCompressEnd歸還相關(guān)資源給系統(tǒng);ICDompressQuery詢問decompressor是否支持某種解壓縮方式;ICDompressBegin要求系統(tǒng)準(zhǔn)備相關(guān)資源以供解壓縮之用;ICDompress解壓縮某一個(gè)frame;ICDompressEnd歸還相關(guān)資源給系統(tǒng);ICDompressFree歸還COMPVARS所占用的資源。線程的實(shí)現(xiàn)方法線程是一個(gè)獨(dú)立的執(zhí)行流,是進(jìn)程內(nèi)部的一個(gè)獨(dú)立的執(zhí)行單元,相當(dāng)于一個(gè)子程序,它對(duì)應(yīng)于VisualC++中的CWinThread類對(duì)象。單獨(dú)一個(gè)執(zhí)行程序運(yùn)行時(shí),缺省地包含了一個(gè)主線程,主線程以函數(shù)地址的形式出現(xiàn),提供程序的啟動(dòng)點(diǎn),當(dāng)主線程終止時(shí),進(jìn)程也隨之終止。根據(jù)實(shí)際需要,應(yīng)用程序可以分解成許多獨(dú)立執(zhí)行的線程,每個(gè)線程并行的運(yùn)行在同一進(jìn)程中。一個(gè)進(jìn)程中的所有線程都在該進(jìn)程的虛擬地址空間中,使用該進(jìn)程的全局變量和系統(tǒng)資源。操作系統(tǒng)給每個(gè)線程分配不同的CPU時(shí)間片,在某一個(gè)時(shí)刻,CPU只執(zhí)行一個(gè)時(shí)間片內(nèi)的線程,多個(gè)時(shí)間片中的相應(yīng)線程在CPU內(nèi)輪流執(zhí)行,由于每個(gè)時(shí)間片時(shí)間很短,所以對(duì)用戶來(lái)說,仿佛各個(gè)線程在計(jì)算機(jī)中是并行處理的。操作系統(tǒng)是根據(jù)線程的優(yōu)先級(jí)來(lái)安排CPU的時(shí)間,優(yōu)先級(jí)高的線程優(yōu)先運(yùn)行,優(yōu)先級(jí)低的線程則繼續(xù)等待。Windows提供了兩種線程:用戶界面線程和工作線程(又稱為后臺(tái)線程)。用戶界面線程通常用來(lái)處理用戶的輸入并響應(yīng)各種事件和消息,其實(shí),應(yīng)用程序的主執(zhí)行線程CWinApp對(duì)象就是一個(gè)用戶界面線程,當(dāng)應(yīng)用程序啟動(dòng)時(shí)自動(dòng)創(chuàng)建和啟動(dòng),同樣它的終止也意味著該程序的結(jié)束,進(jìn)程終止。工作線程用來(lái)執(zhí)行程序的后臺(tái)處理任務(wù),比如計(jì)算、調(diào)度、對(duì)串口的讀寫操作等,它和用戶界面線程的區(qū)別是它不用從CWinThread類派生來(lái)創(chuàng)建,對(duì)它來(lái)說最重要的是如何實(shí)現(xiàn)工作線程任務(wù)的運(yùn)行控制函數(shù)。工作線程和用戶界面線程啟動(dòng)時(shí)要調(diào)用同一個(gè)函數(shù)的不同版本;一個(gè)進(jìn)程中的所有線程共享它們父進(jìn)程的變量,但同時(shí)每個(gè)線程可以擁有自己的變量。這里主要介紹用戶界面線程的運(yùn)用:線程的啟動(dòng)創(chuàng)建一個(gè)用戶界面線程,首先要從類CwinThread產(chǎn)生一個(gè)派生類,同時(shí)必須使DECLARE_DYNCREATE和IMPLEMENT_DYNCREATE來(lái)聲明和實(shí)現(xiàn)這個(gè)CwinThread派生類。第二步是根據(jù)需要重載該派生類的一些成員函數(shù)如:ExitInstance()、InitInstance()、OnIdle()、PreTranslateMessage()等函數(shù)。最后調(diào)用AfxBeginThread()函數(shù)的一個(gè)版本:CWinThread*AfxBeginThread(CRuntimeClass*pThreadClass,intnPriority=THREAD_PRIORITY_NORMAL,UINTnStackSize=0,DWORDdwCreateFlags=0,LPSECURITY_ATTRIBUTESlpSecurityAttrs=NULL)啟動(dòng)該用戶界面線程,其中第一個(gè)參數(shù)為指向定義的用戶界面線程類指針變量,第二個(gè)參數(shù)為線程的優(yōu)先級(jí),第三個(gè)參數(shù)為線程所對(duì)應(yīng)的堆棧大小,第四個(gè)參數(shù)為線程創(chuàng)建時(shí)的附加標(biāo)志,缺省為正常狀態(tài),如為CREATE_SUSPENDED則線程啟動(dòng)后為掛起狀態(tài)。線程的優(yōu)先級(jí)CwinThread類的成員函數(shù)用于線程優(yōu)先級(jí)的操作:intGetThreadPriority();BOOLSetThradPriority()(intnPriority);線程的掛起和恢復(fù)CWinThread類中包含了應(yīng)用程序掛起和恢復(fù)它所創(chuàng)建的線程的函數(shù),其中SuspendThread()用來(lái)掛起線程,暫停線程的執(zhí)行;ResumeThread()用來(lái)恢復(fù)線程的執(zhí)行。如果你對(duì)一個(gè)線程連續(xù)若干次執(zhí)行SuspendThread(),則需要連續(xù)執(zhí)行相應(yīng)次的ResumeThread()來(lái)恢復(fù)線程的運(yùn)行。結(jié)束線程終止線程有三種途徑,線程可以在自身內(nèi)部調(diào)用AfxEndThread()來(lái)終止自身的運(yùn)行;可以在線程的外部調(diào)用BOOLTerminateThread(HANDLEhThread,DWORDdwExitCode)來(lái)強(qiáng)行終止一個(gè)線程的運(yùn)行,然后調(diào)用CloseHandle()函數(shù)釋放線程所占用的堆棧;第三種方法是改變?nèi)肿兞?,使線程的執(zhí)行函數(shù)返回,則該線程終止。需求分析軟硬件環(huán)境電腦兩臺(tái)以上,分別配有攝像頭、麥克風(fēng)、音箱或耳機(jī)等外部設(shè)備;WindowsXP系統(tǒng),MicrosoftVisualStudio6.0編程開發(fā)系統(tǒng)等。需求分析在同一個(gè)局域網(wǎng)中,如何根據(jù)自身業(yè)務(wù)的要求,量身定制,對(duì)視頻設(shè)備進(jìn)行合理搭配,選擇一套合理的視頻聊天室系統(tǒng)。如何來(lái)滿足局域網(wǎng)內(nèi)部用戶的通訊要求,在考慮到網(wǎng)絡(luò)帶寬的同時(shí),提高視頻清晰度,動(dòng)態(tài)畫面的流暢,語(yǔ)音的實(shí)時(shí)傳輸?shù)?,正是現(xiàn)代社會(huì)通訊所必需的。設(shè)計(jì)本系統(tǒng)時(shí),分析網(wǎng)絡(luò)承載、整個(gè)系統(tǒng)結(jié)構(gòu)的組建等是實(shí)現(xiàn)局域網(wǎng)文字聊天和語(yǔ)音視頻聊天所必需的。文字、語(yǔ)音視頻聊天作為一種廣泛的網(wǎng)絡(luò)應(yīng)用對(duì)其基礎(chǔ)的承載網(wǎng)絡(luò)環(huán)境有著較高的網(wǎng)絡(luò)要求。其中應(yīng)重點(diǎn)考慮的是網(wǎng)絡(luò)的帶寬情況、端到端的時(shí)延、時(shí)延抖動(dòng)、丟包率等問題。網(wǎng)絡(luò)帶寬需求,視頻聊天對(duì)網(wǎng)絡(luò)的帶寬需求為“視頻帶寬+IP包頭開銷”,計(jì)算方法為:網(wǎng)絡(luò)帶寬=視頻帶寬×1.2。端到端的時(shí)延,網(wǎng)絡(luò)傳輸不可避免的會(huì)發(fā)生傳輸時(shí)延,通常建議視頻聊天的通用時(shí)延小于150ms。時(shí)延抖動(dòng),由于音頻/視頻的傳輸為實(shí)時(shí)的交互,因此網(wǎng)絡(luò)的時(shí)延抖動(dòng)更為重要,一般,視頻聊天的時(shí)延抖動(dòng)控制在50ms內(nèi)。丟包率,網(wǎng)絡(luò)數(shù)據(jù)傳輸經(jīng)常會(huì)出現(xiàn)丟包現(xiàn)象,視頻傳輸過程中數(shù)據(jù)丟包嚴(yán)重的話會(huì)影響在線視頻聊天質(zhì)量。因此,在設(shè)計(jì)上應(yīng)將網(wǎng)絡(luò)上的丟包率控制在1%以內(nèi)。視頻聊天對(duì)實(shí)時(shí)性要求較高的網(wǎng)絡(luò)應(yīng)用,作為其基礎(chǔ)的承載網(wǎng)絡(luò)有較高的寬帶和對(duì)網(wǎng)絡(luò)中的業(yè)務(wù)流量有較高的控制能力。而視頻聊天系統(tǒng)本身對(duì)帶寬的要求為62kbit/s~2Mbit/s,但是為了滿足流暢的視音頻效果,要求帶寬不低于384kbit/s。文字、視頻聊天的功能和應(yīng)用效果體現(xiàn)在客戶端,而服務(wù)器端則是必不可少的,對(duì)于系統(tǒng)的需求分析在系統(tǒng)設(shè)計(jì)的過程中應(yīng)該明確、細(xì)致:文字聊天:首先啟動(dòng)服務(wù)器端,當(dāng)用戶啟動(dòng)客戶端時(shí),用服務(wù)器保存的用戶名和密碼來(lái)驗(yàn)證客戶是否已經(jīng)登錄到服務(wù)器。只有當(dāng)有兩個(gè)以上的用戶啟動(dòng)客戶端時(shí),才可以進(jìn)行文字聊天,聊天內(nèi)容要經(jīng)過服務(wù)器中轉(zhuǎn),分別在服務(wù)器端和兩個(gè)聊天的客戶端顯示聊天。語(yǔ)音視頻聊天:在有兩個(gè)客戶在線的情況下,才能進(jìn)行語(yǔ)音視頻聊天。兩個(gè)用戶要進(jìn)行語(yǔ)音視頻聊天時(shí),一個(gè)用戶選中另一個(gè)用戶的用戶名,根據(jù)該用戶名在后臺(tái)鏈表中的對(duì)應(yīng)IP地址查找用戶并請(qǐng)求視頻連接。當(dāng)雙方確認(rèn)視頻連接后就進(jìn)行視頻傳輸,并顯示在客戶端,同時(shí)用線程實(shí)現(xiàn)語(yǔ)音錄制和回放。這樣,兩個(gè)用戶就實(shí)現(xiàn)了點(diǎn)對(duì)點(diǎn)的語(yǔ)音視頻聊天。在進(jìn)行語(yǔ)音視頻聊天的過程中,不能再與其它用戶進(jìn)行語(yǔ)音視頻聊天,但能夠與其它用戶進(jìn)行文字聊天。系統(tǒng)結(jié)構(gòu)硬件結(jié)構(gòu)該系統(tǒng)采用的是Server/Client結(jié)構(gòu),服務(wù)器端是一臺(tái)PC機(jī),而客戶端是PC機(jī)和一個(gè)數(shù)字?jǐn)z像頭、耳機(jī)和麥克風(fēng)。它們進(jìn)行文字聊天時(shí),要經(jīng)過服務(wù)器進(jìn)行中轉(zhuǎn),而當(dāng)進(jìn)行語(yǔ)音視頻聊天時(shí)是客戶端與客戶端之間直接進(jìn)行的點(diǎn)對(duì)點(diǎn)的連接,它們之間的網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)如圖1。在圖中,為了簡(jiǎn)便,沒有畫出麥克風(fēng)、音箱或耳機(jī)等外部設(shè)備。圖1網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)圖軟件結(jié)構(gòu)功能需求通過需求調(diào)研并分析,確定系統(tǒng)具備的基本功能,包括:文字聊天、語(yǔ)音視頻聊天。文字聊天:文字聊天采用的是TCP模式,包括服務(wù)器端和客戶端。首先啟動(dòng)服務(wù)器端,客戶端通過用戶名和密碼登錄服務(wù)器,服務(wù)器響應(yīng)客戶端登錄并提示有用戶登錄,此時(shí)兩個(gè)用戶就可以進(jìn)行文字聊天,在文字聊天時(shí)通過服務(wù)器中轉(zhuǎn),而每個(gè)用戶可以同時(shí)與多個(gè)用戶進(jìn)行文字聊天。當(dāng)有用戶退出時(shí),服務(wù)器做出響應(yīng),提示在線用戶,××用戶下線。語(yǔ)音視頻聊天:語(yǔ)音視頻聊天時(shí)采用的是UCP模式,客戶端與客戶端點(diǎn)對(duì)點(diǎn)的進(jìn)行,不需要經(jīng)過服務(wù)器端中轉(zhuǎn)。在文字聊天的基礎(chǔ)上,客戶端之間自行處理的語(yǔ)音視頻聊天,運(yùn)用VFW函數(shù)庫(kù)中的函數(shù)對(duì)USB口輸入的數(shù)字視頻信息進(jìn)行相關(guān)處理,比如:視頻捕獲、影像壓縮以及影像播放等,同時(shí)利用線程來(lái)處理聲音部分的錄制、回放等。A客戶端向B客戶端請(qǐng)求語(yǔ)音視頻聊天是通過B客戶端的用戶名來(lái)獲得B客戶端的IP地址,并向B客戶端發(fā)送語(yǔ)音視頻聊天請(qǐng)求,當(dāng)B客戶端接受后捕獲視頻,并進(jìn)行壓縮傳輸?shù)紸客戶端解壓并進(jìn)行顯示,在B客戶端接受視頻的同時(shí),A客戶端也捕獲視頻,壓縮傳輸?shù)紹客戶端解壓并進(jìn)行顯示。系統(tǒng)功能模塊圖該系統(tǒng)分為服務(wù)器端和客戶端,完成了文字聊天和語(yǔ)音視頻聊天,使用上只有文字聊天時(shí)才會(huì)通過服務(wù)器端,而對(duì)于語(yǔ)音視頻聊天就只需要對(duì)整個(gè)在線客戶端兩兩之間進(jìn)行點(diǎn)對(duì)點(diǎn)的視頻聊天。而在語(yǔ)音視頻時(shí)包括了視頻捕獲、視頻壓縮、解壓縮、語(yǔ)音錄制、語(yǔ)音回放以及視頻傳輸?shù)?。整個(gè)系統(tǒng)的功能模塊圖如圖2。圖2系統(tǒng)功能模塊圖系統(tǒng)各模塊流程圖在整個(gè)系統(tǒng)中主要運(yùn)行兩個(gè)功能:圖3文字聊天流程圖和圖4語(yǔ)音視頻聊天流程圖。圖3文字聊天流程圖圖4語(yǔ)音視頻聊天流程圖系統(tǒng)的詳細(xì)設(shè)計(jì)文字聊天TCP套接字的運(yùn)用在文字聊天時(shí),服務(wù)器端與客戶端的連接是采用的TCP套接節(jié)進(jìn)行連接。TCP套接字的使用如圖5。創(chuàng)建CSocket對(duì)象CSocketServer來(lái)處理服務(wù)器端與客戶端的連接,CSocket繼承于CasyncSocket,是WindowsSocketAPI的高層抽象。CSocket通常和CsocketFile以及Carchive類混合使用,這兩個(gè)類負(fù)責(zé)數(shù)據(jù)的發(fā)送和接收。要使用CSocket對(duì)象,首先要調(diào)用構(gòu)造函數(shù),然后調(diào)用Create函數(shù)創(chuàng)建一個(gè)Socket句柄。CSocket函數(shù)缺省是創(chuàng)建一個(gè)流Socket;如果沒有使用CArchive類,那么還可以創(chuàng)建一個(gè)數(shù)據(jù)報(bào)Socket。服務(wù)器端調(diào)用Accept,客戶端調(diào)用Connect,然后創(chuàng)建一個(gè)CsocketFile去關(guān)聯(lián)CSocket。接下來(lái)的操作可以創(chuàng)建CArchive對(duì)象關(guān)聯(lián)CsocketFile,以用來(lái)發(fā)送和接收數(shù)據(jù)。圖5TCP套接字的使用文字聊天實(shí)現(xiàn)ChatServer服務(wù)器運(yùn)行時(shí),利用一個(gè)CSocket對(duì)象CSocketServer啟動(dòng)服務(wù)器,用函數(shù)gethostname來(lái)獲得服務(wù)器端主機(jī)名和IP,同時(shí)在服務(wù)器對(duì)話框中顯示服務(wù)器IP,并將分配的固定端口號(hào)8123顯示在對(duì)話框中。用一個(gè)list列表顯示在線用戶,隨時(shí)更新用戶登錄情況,用一個(gè)editbox顯示客戶端的聊天內(nèi)容以及系統(tǒng)提示消息。每一個(gè)ChatClient客戶端啟動(dòng)時(shí),利用服務(wù)器內(nèi)定的用戶號(hào)和密碼來(lái)登錄(如圖6)。在整個(gè)系統(tǒng)中,利用鏈表來(lái)處理所有的用戶信息:當(dāng)有用戶登錄時(shí),在鏈表尾部加入該用戶信息;當(dāng)用戶下線時(shí),在該鏈表中刪除用戶,并提示所有用戶,該用戶下線。在對(duì)鏈表進(jìn)行操作的同時(shí),要更新list列表中的信息。圖6用戶登錄界面ChatServer服務(wù)器端響應(yīng)客戶端文字聊天時(shí)的中轉(zhuǎn)情況如圖7。圖7服務(wù)器響應(yīng)文字聊天信息中轉(zhuǎn)ChatClient客戶端兩兩間進(jìn)行文字聊天時(shí),發(fā)送信息的處理函數(shù)如下:voidCChatClientDlg::OnChatBtSend()//發(fā)送信息按鍵{ if(!m_bConnect) { SetMessageBox("請(qǐng)連接服務(wù)器!\r\n"); return; } CStringstr; CStringszUserName; CMesgmsg; GetDlgItemText(IDC_MESSAGE,str); GetDlgItemText(IDC_USERNAME,szUserName); if(str.GetLength()<=0) { SetMessageBox("請(qǐng)輸入想要發(fā)送的信息!\r\n"); return; } if(szUserName.GetLength()<=0) { SetMessageBox("請(qǐng)選擇說話對(duì)象!\r\n"); return; } //消息封裝 msg.m_szCommand.Format("Message"); msg.m_szRecObject.Format(szUserName); msg.m_szText.Format(str); m_csClient->SendM(&msg); AddReceiver(szUserName,true); AddChatMessage(str);}在聊天兩個(gè)客戶端的信息情況如圖8和圖9。圖8接收文字信息圖9發(fā)送文字信息語(yǔ)音視頻聊天UDP套接字的運(yùn)用在實(shí)現(xiàn)語(yǔ)音視頻聊天時(shí),采用的是基于UDP套接字的點(diǎn)對(duì)點(diǎn)模式,而UDP面向的是無(wú)連接的數(shù)據(jù)服務(wù),其套接字的使用如圖10所示。圖10UDP套接字的使用視頻的捕獲利用VFW接口,視頻捕獲可以分為以下幾個(gè)步驟:建立視頻采集窗口:該窗口用來(lái)接收視頻捕捉驅(qū)動(dòng)程序傳來(lái)的數(shù)據(jù)和消息。連接視頻驅(qū)動(dòng)程序:將建立的視頻捕捉窗口與視頻設(shè)備驅(qū)動(dòng)程序相連。視頻捕獲初始化。視頻捕捉設(shè)置:VFW下視頻捕捉參數(shù)的設(shè)置可以通過調(diào)用函數(shù)或彈出對(duì)話框的形式來(lái)實(shí)現(xiàn)。一般視頻驅(qū)動(dòng)程序允許設(shè)置的參數(shù)包括視頻源選擇、視頻格式、視頻顯示格式等。設(shè)置回調(diào)函數(shù):通過回調(diào)函數(shù)來(lái)通知程序視頻事件的發(fā)生,比如捕捉一幀圖像成功的消息,捕捉出錯(cuò)的消息等。結(jié)束捕捉:結(jié)束捕捉是應(yīng)該有一些清除工作。如釋放分配的內(nèi)存,斷開捕捉窗口與視頻捕捉驅(qū)動(dòng)程序的連接,清除視頻捕捉窗口等。窗口類為捕獲數(shù)字視頻流及其相關(guān)操作提供了很大的方便,靈活編寫其中的回調(diào)函數(shù)可滿足實(shí)時(shí)視頻傳輸?shù)男枰?,例如?yīng)用程序可直接從緩沖中取得數(shù)字視頻并對(duì)其進(jìn)行壓縮編碼后實(shí)時(shí)地傳到遠(yuǎn)端的客戶端。在VC++中,采用VFW技術(shù),客戶端通過capSetCallbackOnFrame()注冊(cè)回調(diào)函數(shù),當(dāng)采集卡采集到一幅圖像后,系統(tǒng)就會(huì)自動(dòng)調(diào)用回調(diào)函數(shù),然后再回調(diào)函數(shù)中使用ICSeqCompressFrame()函數(shù)進(jìn)行壓縮。然后再通過Winsock將壓縮后的數(shù)據(jù)發(fā)送到另一客戶端。該客戶端接收完一幀以后,交給ICDecompress()解壓,最后用SetDIBitsToDevice()將圖像顯示出來(lái)?;镜牟东@設(shè)置包括設(shè)置捕獲速度(每秒捕獲多少幀)、是否同時(shí)捕獲聲頻、捕獲緩沖、允許最大丟失多少幀和是否使用DOS內(nèi)存,以及使用鍵盤的哪個(gè)鍵或鼠標(biāo)的哪個(gè)鍵來(lái)終止捕獲等內(nèi)容,這些設(shè)置使用CAPTUREPARAMS結(jié)構(gòu)來(lái)描述,capCaptureGetSetup宏來(lái)得到當(dāng)前的設(shè)置,然后改變此結(jié)構(gòu)的成員變量,再使用capCaptureSetSetup宏設(shè)置新的設(shè)置。設(shè)置捕獲速度,通過使用capCaptureGetSetup宏來(lái)得到當(dāng)前的捕捉速度,將當(dāng)前的捕捉速度保存在CAPTUREPARAMS結(jié)構(gòu)的dwRequestMicroSecPerFrame成員變量中,也可以通過設(shè)置此變量來(lái)改變當(dāng)前設(shè)置值。設(shè)置終止捕獲,同樣通過使用capCaptureGetSetup宏來(lái)得到當(dāng)前的設(shè)置,當(dāng)前按鍵設(shè)置保存在CAPTUREPARAMS結(jié)構(gòu)的vKeyAbort成員中,鼠標(biāo)設(shè)置保存在fAbortLeftMouse和fAbortRightMouse成員中,通過修改可以設(shè)置新的熱健或者鼠標(biāo)左右鍵,修改完成后,使用capCaptureSetSetup宏來(lái)進(jìn)行更新。捕獲的時(shí)間限制,用CAPTUREPARAMS結(jié)構(gòu)中的fLimitEnabled表示捕獲是否有時(shí)間的限制,wTimeLimit用來(lái)設(shè)置指示捕獲最大的持續(xù)時(shí)間,其單位為秒。使用capCaptureGetSetup宏來(lái)得到當(dāng)前的設(shè)置值。下面程序?yàn)樵O(shè)置CAPTUREPARAMS結(jié)構(gòu)的實(shí)現(xiàn)代碼:BOOLVideoCapture::SetCapturePara(){ CAPTUREPARMSCapParms={0}; capCaptureGetSetup(m_capwnd,&CapParms,sizeof(CapParms)); //得到當(dāng)前的捕獲速度 CapParms.fAbortLeftMouse=FALSE; CapParms.fAbortRightMouse=FALSE; CapParms.fYield=TRUE; CapParms.fCaptureAudio=FALSE; CapParms.wPercentDropForError=80; if(!capCaptureSetSetup(m_capwnd,&CapParms,sizeof(CapParms))) {// log.WriteString("\nFailedtosetthecaptureparameters"); returnFALSE; } //SetVideoFormat capGetVideoFormat(m_capwnd,&m_bmpinfo,sizeof(m_bmpinfo)); m_bmpinfo.bmiHeader.biWidth=IMAGE_WIDTH; m_bmpinfo.bmiHeader.biHeight=IMAGE_HEIGHT; BOOLret=capSetVideoFormat(m_capwnd,&m_bmpinfo,sizeof(m_bmpinfo));// log.WriteString("\nVideoparameterssetproperly"); returnret;}//終止一個(gè)捕獲任務(wù)BOOLVideoCapture::StopCapture(){ capCaptureStop(m_capwnd); capCaptureAbort(m_capwnd); Sleep(500); returnTRUE;}捕獲窗口在捕獲前必須創(chuàng)建一個(gè)捕獲窗口(CaptureWidnow),下面介紹有關(guān)捕獲窗口的情況:創(chuàng)建一個(gè)AVICap捕獲窗口,用capCreateCaptureWindow函數(shù)并返回一個(gè)句柄。將捕獲窗口連接至捕獲設(shè)備,用capDriverConnect函數(shù)來(lái)使一個(gè)捕獲窗口與一個(gè)捕獲設(shè)備連接或關(guān)聯(lián)連接上后,就可以通過捕獲窗口向捕獲設(shè)備發(fā)送各種消息,可以使用函數(shù)capGetDriverDescription來(lái)獲得已安裝的捕獲設(shè)備名稱及版本,將其列舉在實(shí)現(xiàn)程序過程中。再利用capDriverGetName函數(shù)來(lái)得到捕獲設(shè)備的名稱將獲得的版本發(fā)送到capDriverGetVersion。如果斷開捕獲窗口與捕獲設(shè)備的連接用capDriverDisconnect。捕獲窗口的狀態(tài),用capGetStatus函數(shù)來(lái)獲得當(dāng)前捕獲窗口的狀態(tài),得到一個(gè)CAPSTATUS結(jié)構(gòu)的拷貝。該結(jié)構(gòu)的內(nèi)容包含了圖片的尺寸、卷軸的當(dāng)前位置、overlay和preview是否已設(shè)置。由于其信息是動(dòng)態(tài)的,每當(dāng)捕獲的視頻流的尺寸發(fā)生改變,程序應(yīng)該在獲取捕獲設(shè)備的視頻格式以后及時(shí)進(jìn)行刷新。而捕獲窗口尺寸的改變并不影響實(shí)際的捕獲視頻流的尺寸。該尺寸由視頻捕獲設(shè)備的格式和視頻對(duì)話框決定。//捕獲窗口BOOLVideoCapture::Initialize(){ chardevname[128]={0},devversion[128]={0};intindex=0;BOOLret=TRUE,ret1=TRUE,ret2=TRUE,ret3=TRUE;TRACE("VideoCapture::Initialize\n");//創(chuàng)建一個(gè)AVICap捕獲窗口m_capwnd=capCreateCaptureWindow("Capture",WS_POPUP,0,0,1,1,0,0); if(!m_capwnd) { returnFALSE; } //connectcallbackfunctions ret=capSetUserData(m_capwnd,this); //Changedestroyfunctionsalsoret1=capSetCallbackOnVideoStream(m_capwnd,OnCaptureVideo);//得到已安裝的捕獲設(shè)備的名稱及版本 ret2=capGetDriverDescription(index,devname,100,devversion,100); //Connecttowebcamdriver //使一個(gè)捕獲窗口與一個(gè)捕獲設(shè)備連接或關(guān)聯(lián) ret3=capDriverConnect(m_capwnd,index); if(!(ret&&ret1&&ret2&&ret3)) { //Devicemaybeopenalreadyoritmaynothavebeen //closedproperlylasttime. AfxMessageBox("UnabletoopenVideoCaptureDevice"); // log.WriteString("\nUnabletoconnectdrivertothewindow"); m_capwnd=NULL; returnFALSE; } //Setthecaptureparameters if(SetCapturePara()==FALSE) {// log.WriteString("\nSettingcaptureparametersfailed"); capDriverDisconnect(m_capwnd);//使捕獲窗口與一個(gè)捕獲設(shè)備斷開 returnFALSE; } returnTRUE;}視頻捕獲驅(qū)動(dòng)視頻捕獲必須具有視頻捕獲驅(qū)動(dòng)才能進(jìn)行,其相關(guān)內(nèi)容如下:視頻捕獲驅(qū)動(dòng)的性能,capDriverGetCap函數(shù)得到當(dāng)前連接視頻驅(qū)動(dòng)的硬件性能,該信息保存在CAPDRIVERCAPS結(jié)構(gòu)中;視頻對(duì)話框,每個(gè)視頻驅(qū)動(dòng)能夠提供4個(gè)對(duì)話框來(lái)控制視頻捕獲和數(shù)字化處理視頻對(duì)話框定義的視頻壓縮率和圖像品質(zhì)等。視頻對(duì)話框都在視頻捕獲驅(qū)動(dòng)中定義。這個(gè)四個(gè)對(duì)話框分別為:VideoSource對(duì)話框用于控制選擇視頻來(lái)源(capDlgVideoSource);VideoFormat對(duì)話框定義視頻幀的尺寸和精度,以及視頻捕獲卡的壓縮設(shè)置(capDlgVideoFormat);VideoDisplay對(duì)話框控制在視頻捕獲期間相關(guān)顯示器上的顯示(capDlgVideoDisplay);VideoCompression對(duì)話框控制壓縮和圖像品質(zhì)(caoDlgVideoCompression)。語(yǔ)音錄制在音頻的錄制和播放時(shí),采用的用戶界面線程來(lái)處理,是CWinThread對(duì)象,根據(jù)前面線程的介紹,一步一步的來(lái)實(shí)現(xiàn)。錄音用的一個(gè)CWinThread對(duì)象CAudioRec來(lái)實(shí)現(xiàn),部分實(shí)現(xiàn)代碼:LRESULTCAudioRec::OnStartRecording(WPARAMwp,LPARAMlp){ if(recording) returnFALSE; //打開錄音設(shè)備 MMRESULTmmReturn=::waveInOpen(&m_hRecord,WAVE_MAPPER, &m_WaveFormatEx,::GetCurrentThreadId(),0,CALLBACK_THREAD); if(mmReturn!=MMSYSERR_NOERROR) returnFALSE; if(mmReturn==MMSYSERR_NOERROR) { for(inti=0;i<MAXRECBUFFER;i++) { //為錄音設(shè)備準(zhǔn)備緩存 mmReturn=::waveInPrepareHeader(m_hRecord,rechead[i],sizeof(WAVEHDR)); //給輸入設(shè)備增加一個(gè)緩存 mmReturn=::waveInAddBuffer(m_hRecord,rechead[i],sizeof(WAVEHDR)); } mmReturn=::waveInStart(m_hRecord);//開始錄音 if(mmReturn==MMSYSERR_NOERROR) recording=TRUE; } returnTRUE;}語(yǔ)音回放相對(duì)錄音而言,播放就簡(jiǎn)單多了,同樣用的一個(gè)CWinThread對(duì)象CAudioPlay來(lái)實(shí)現(xiàn),部分實(shí)現(xiàn)代碼:LRESULTCAudioPlay::OnWriteSoundData(WPARAMwParam,LPARAMlParam){// TRACE("CAudioPlay::OnWriteSoundData\n"); MMRESULTmmResult=FALSE; char*p=NULL; intlength=(int)wParam; if(Playing==FALSE) returnFALSE; if(length<=0) returnFALSE; WAVEHDR*lpHdr=newWAVEHDR; if(!lpHdr) returnFALSE; p=newchar[length]; if(!p) {deletelpHdr; returnFALSE;} ZeroMemory(lpHdr,sizeof(WAVEHDR)); ZeroMemory(p,length); CopyMemory(p,(char*)lParam,length); lpHdr->lpData=p; lpHdr->dwBufferLength=length; mmResult=::waveOutPrepareHeader(m_hPlay,lpHdr,sizeof(WAVEHDR));//為回放設(shè)備準(zhǔn)備內(nèi)存塊 if(mmResult) { deletelpHdr;deletep; returnmmResult; } mmResult=::waveOutWrite(m_hPlay,lpHdr,sizeof(WAVEHDR));//寫數(shù)據(jù)(放音) if(mmResult){deletelpHdr;deletep; returnmmResult;} m_Count++; returnMMSYSERR_NOERROR;}視音頻的傳輸視頻采集采用AVICap從視頻采集卡捕獲視頻圖像,得到的是位圖形式的視頻幀,然后用Divx編碼器進(jìn)行壓縮,壓縮以后形成以幀為格式的Mpeg4流。通過Winsock實(shí)現(xiàn)壓縮后的視頻數(shù)據(jù)在局域網(wǎng)中的實(shí)時(shí)傳輸,接收完的數(shù)據(jù)交給Divx解碼器,以幀的格式解壓,最后實(shí)現(xiàn)視頻顯示。所以提出以幀為單位發(fā)送視頻數(shù)據(jù)流。為了在接收端能夠方便地提取出一幀,提出如表1所示的格式組建幀。完整的一幀由5個(gè)字段組成,各個(gè)字段的意義如下:幀開始標(biāo)志:標(biāo)志著一幀地開始,占用4個(gè)字節(jié)的空間;幀大?。?/p>

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論