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