Window平台实时流媒体
生活随笔
收集整理的這篇文章主要介紹了
Window平台实时流媒体
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
壓縮包可以從這里獲得:http://www.bairuitech.com/upimg/soft/jrtplib-3.7.1.rar
? 下載jrtplib-3.7.1.rar后,首先將其解壓到一個臨時文件夾中,然后開始后續(xù)工作。 首先需要強(qiáng)調(diào)的是,jrtplib是一個庫而不是應(yīng)用程序,編譯后我們獲得的是.lib文件。這個文件是用來實現(xiàn)RTP協(xié)議的,意義和我們在寫WIN32程序時用到的kernel.lib一樣。 解壓后的文件夾中包含兩個目錄,jrtplib-3.7.1和jthread-1.2.1,打開這兩個目錄后我們可以看到下面又有兩個同名的目錄,為了后面能順利編譯,我們把同名目錄下的文件全部考到上一級目錄中,就是說把f:\jrtplib-3.7.1\jrtplib-3.7.1\*.* 復(fù)制到f:\jrtplib-3.7.1\。同理,把f:\jthread-1.2.1\jthread-1.2.1\*.* 復(fù)制到f:\jthread-1.2.1\ 完成上述步驟后我們就可以開始編譯庫文件了。 Windows平臺下建議使用Visual C++6.0。 首先編譯多線程庫jthread,在vc6中直接打開工作區(qū)文件jthread.dsw,改變工程設(shè)置,選中source file下的文件,點右鍵選擇setting,確保code generation下Use run-time library 為debug mulitithreaded DLL或debug mulitithreaded。
b) Link中添加ws2_32.lib
? 下載jrtplib-3.7.1.rar后,首先將其解壓到一個臨時文件夾中,然后開始后續(xù)工作。 首先需要強(qiáng)調(diào)的是,jrtplib是一個庫而不是應(yīng)用程序,編譯后我們獲得的是.lib文件。這個文件是用來實現(xiàn)RTP協(xié)議的,意義和我們在寫WIN32程序時用到的kernel.lib一樣。 解壓后的文件夾中包含兩個目錄,jrtplib-3.7.1和jthread-1.2.1,打開這兩個目錄后我們可以看到下面又有兩個同名的目錄,為了后面能順利編譯,我們把同名目錄下的文件全部考到上一級目錄中,就是說把f:\jrtplib-3.7.1\jrtplib-3.7.1\*.* 復(fù)制到f:\jrtplib-3.7.1\。同理,把f:\jthread-1.2.1\jthread-1.2.1\*.* 復(fù)制到f:\jthread-1.2.1\ 完成上述步驟后我們就可以開始編譯庫文件了。 Windows平臺下建議使用Visual C++6.0。 首先編譯多線程庫jthread,在vc6中直接打開工作區(qū)文件jthread.dsw,改變工程設(shè)置,選中source file下的文件,點右鍵選擇setting,確保code generation下Use run-time library 為debug mulitithreaded DLL或debug mulitithreaded。
?然后選build就可以了,和上面一樣的方法完成jrtpthread的編譯。這個底下的文件比jthread多一些。
默認(rèn)產(chǎn)生的文件是jthread.lib和jrtplib.Lib,這兩個文件分別位于兩個文件夾下的debug文件夾下,將它們復(fù)制到VC6的lib文件夾下。 完成上述工作后我們就可以開始嘗試編譯jrtplib附帶的examples。 創(chuàng)建一個新的Win32 Console 應(yīng)用程序項目,添加example文件到source files文件夾中,然后添加jrtplib工程下的所有.h頭文件,這里我們可以用VC6提供的一個功能偷懶:)將jrtplib項目添加到本工作區(qū),然后將Header Files下的所有文件復(fù)制到我們創(chuàng)建的工程的Header Files文件夾里面。 修改example.cpp文件,在文件開始添加 #pragma comment(lib, "jrtplib.lib") #pragma comment(lib, "jthread.lib") #pragma comment(lib, "WS2_32.lib") 或者在VC中a) Project->Settings->Link中Object/library modules:添加jthread.lib jrtplib.lib,b) Link中添加ws2_32.lib
?
檢查code generationdebug mulitithreaded DLL或debug mulitithreaded,方法同上文中檢查庫文件的方法。 最后就可以編譯、連接、生成可執(zhí)行文件了。 3、具體流程圖 一.??? 調(diào)試記錄 (1). 輸入端口,IP后出錯 ERROR: Can't retrieve login name 這是rtpsession.cpp中的createCNAME函數(shù)有問題 if (!gotlogin) ? { ? //???? char *logname = getenv("LOGNAME"); ???????? if (logname == 0) ??????????????? return ERR_RTP_SESSION_CANTGETLOGINNAME; ? ?????? strncpy((char *)buffer,logname,*bufferlength); ? } logname要求獲得登陸名,而板子一般沒有登陸名,將其強(qiáng)制改為root即可 if (!gotlogin) ? { ? //???? char *logname = getenv("LOGNAME"); ???????? char *logname = "root"; ???????? if (logname == 0) ??????????????? return ERR_RTP_SESSION_CANTGETLOGINNAME; ???????? strncpy((char *)buffer,logname,*bufferlength); ? } (2)板子和PC收發(fā)數(shù)據(jù)不能接收 在PC和板子上同時運行jrtplib例子程序example1(此程序可同時收發(fā)),在PC和板子之間收發(fā)數(shù)據(jù),程序能夠運行但雙方都接收不到數(shù)據(jù),結(jié)果如下: 查閱資料發(fā)現(xiàn)是字節(jié)序和位域的問題,一般x86的pc機(jī)是用小端字節(jié)序(little endian),而嵌入式平臺一般是大端字節(jié)序(big endian),可能是由于字節(jié)序的不同,導(dǎo)致了明明存在數(shù)據(jù)包,卻認(rèn)不出來的問題。 這是一個位域結(jié)構(gòu)體,jrtplib庫使用哪種字節(jié)序完全取決于RTP_BIG_ENDIAN的定義,這樣問題就簡單化了。 ?? ??看了一下我編譯arm下jrtplib庫的rtpconfig_unix.h這個文件,里面果然定義了一個RTP_BIG_ENDIAN,所以要和pc采用的小端字節(jié)序一樣,先是直接在rtpconfig_unix.h中注釋掉了 然后在重新編譯庫,執(zhí)行 ./configure –host=arm-linux –prefix=/usr/local/arm/2.95.3 make make install 完了再次運行example1,還是不行,查看rtpconfig_unix.h發(fā)現(xiàn)剛注釋掉到內(nèi)容又恢復(fù)了, 最后查找發(fā)現(xiàn)是此文件是由./configure命令生成的,所以先執(zhí)行./configure命令,然后再注釋上面的內(nèi)容,最后 make make install 編譯完成再次運行example1,能受到數(shù)據(jù)包,結(jié)果如下: (3)自己寫的接收程序?qū)懳募鲥e 接收端程序是在example3的基礎(chǔ)上修改的,收到到數(shù)據(jù)包信息全部存在 RTPPacket *pack; 這個類指針當(dāng)中,可以通過 uint8_t *data; size_t *length; data=pack->GetPayloadData(); length=pack->getPayloadLength(); 提取出負(fù)載數(shù)據(jù)和負(fù)載長度。 收到數(shù)據(jù)以后以文件形式存下來。 if((write(outfile,data,length))<0) ? { ? ?????? perror("write outfile error;"); ? ?????? return -1; ? } 最開始把打開文件放在開頭,寫入文件放在接收數(shù)據(jù)之后,但一直不能正確寫文件,提示: bad file descriptor 后來發(fā)現(xiàn)把打開文件放到寫文件之前(即在接收數(shù)據(jù)到while循環(huán)之內(nèi))可以正確寫數(shù)據(jù),分析原因覺得可能是由于接收程序是一個多線程控制的而引起的。但是這樣每次接收都要打開文件,會導(dǎo)致接收速度變慢,試著把打開文件放到循環(huán)外邊發(fā)現(xiàn)也可以正確寫數(shù)據(jù),具體是什么原因?qū)е逻@樣暫時還不清楚。 (4)接收數(shù)據(jù)時有數(shù)據(jù)丟失現(xiàn)象,發(fā)送端發(fā)送數(shù)據(jù)時發(fā)現(xiàn)發(fā)送速度太快,所以數(shù)據(jù)瞬間發(fā)完,而不像例子程序一樣一包一包的發(fā)送,最開始一直以為是設(shè)置時戳單元和時戳增量有問題, sessparams.SetOwnTimestampUnit(1.0/1000.0); sess.SetDefaultTimestampIncrement(10); 但改了幾次還是沒有變化,最后仔細(xì)對比例子程序,發(fā)現(xiàn)是 RTPTime ::Wait(RTPTime(0,0)); 這個函數(shù)的位置放錯了,此函數(shù)的作用就是發(fā)完一個包后等待一定時間(其中括號中第一個參數(shù)表示秒,第二個表示微秒),發(fā)送程序中將其放到了while循環(huán)之外,沒有了這個等待時間而接收端還是以此間隔接收數(shù)據(jù)當(dāng)然會丟失數(shù)據(jù)了,將其挪到循環(huán)之內(nèi)就可以了。 二.??? 存在的問題和擬采取的解決方案 現(xiàn)在接收到的數(shù)據(jù)是以文件的形式存下來的,但是最后想要達(dá)到的目的是與MPlayer結(jié)合起來,使視頻采集,壓縮后的數(shù)據(jù)在接收端能夠?qū)崟r的播放出來,現(xiàn)在存在的問題就是如何把收到的數(shù)據(jù)流傳到MPlayer中實時播放,下一階段的工作首先是將MPlayer的源代碼研究清楚,然后再想辦法將接收數(shù)據(jù)實時傳給MPlayer。 對于本博客有任何問題的朋友可加Q:992139738轉(zhuǎn)載于:https://blog.51cto.com/2343338/831528
總結(jié)
以上是生活随笔為你收集整理的Window平台实时流媒体的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: memmove() -- 拷贝内存内容
- 下一篇: linux中ssh连接慢的一种解决方法