生活随笔
收集整理的這篇文章主要介紹了
关于H264通过RTP传输的打包方式
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Q:現(xiàn)在小弟初次嘗試H264的編碼通過(guò)RTP方式傳輸,具體實(shí)驗(yàn)環(huán)境的問(wèn)題如下:
環(huán)境:
服務(wù)器端,H264的幀數(shù)據(jù)(可能超過(guò)64k),分成N個(gè)1460字節(jié)的包,然后加上RTP頭發(fā)送。
客戶(hù)端,VLC播放器,通過(guò)RTSP協(xié)議建立連接,然后接收數(shù)據(jù)解碼播放。
結(jié)果:
VLC不能解碼接收到的數(shù)據(jù),解碼出錯(cuò),VLC的信息中顯示不能解碼幀數(shù)據(jù)。
我已經(jīng)閱讀了一遍rfc3984的文檔,對(duì)里面的如何進(jìn)行打包和用rtp傳輸不是非常理解,希望各位大蝦能夠幫小弟一把,告訴小弟這些和H264的幀該如何發(fā)送,該如何分包,該如何加頭信息等等。
(其中看到FUs的方式好像適合分包發(fā)送,因?yàn)樾〉艿臄?shù)據(jù)幀可能超過(guò)64k,所以忘大蝦們能夠仔細(xì)解釋一下對(duì)于小弟這種情況下的RTP傳輸)
A:我覺(jué)得所有的問(wèn)題在 RFC3984 里面都已經(jīng)說(shuō)得很清楚了。不知道你有哪點(diǎn)不懂,請(qǐng)具體提出來(lái)。
| Q:斑竹好,我這邊是用VLC和服務(wù)器端進(jìn)行通訊的,他們是用RTSP協(xié)議建立開(kāi)始時(shí)的連接的,服務(wù)器返回DISCRIBERS請(qǐng)求的SDP和下面描述的相同,我使用的packetization-mode=1,即FU-As方式打包,因?yàn)槲疫@邊上來(lái)的數(shù)據(jù)幀可能超過(guò)64k數(shù)據(jù)。能否麻煩斑竹看看我這邊的SDP寫(xiě)的是否正確。 SDP: v=0 o=- 1 1 IN IP4 127.0.0.1 s=VStream Live a=type:broadcast t=0 0 c=IN?? IP4 0.0.0.0 m=video 49170 RTP/AVP 99 a=rtpmap:99 H264/90000 a=fmtp:99 profile-level-id=42A01E; packetization-mode=1; sprop-parameter-ets=Z0IACpZTBYmI, aMljiA== a=control:trackID=0
還有就是在RTP發(fā)送時(shí),我打好包的數(shù)據(jù)方式如下面所示: 上來(lái)的幀數(shù)據(jù)為:NALU頭+EBSP數(shù)據(jù) 因?yàn)閹瑪?shù)據(jù)大于1460字節(jié),所以我把數(shù)據(jù)分為N個(gè)不大于1460字節(jié)的包,每個(gè)包前面加上RTP頭發(fā)出去。 其中NALU頭的數(shù)值I幀為0x65,參數(shù)集為0x67和0x68,這個(gè)值是不是有點(diǎn)錯(cuò)誤,我看RFC3984上面說(shuō)的好像和我現(xiàn)在的有點(diǎn)不同,RFC3984上面說(shuō)FU-As方式打包類(lèi)型值為28,我不知道這個(gè)是否十進(jìn)制的,如果按照RFC3984上說(shuō)的NALU頭應(yīng)該是多少?還是用FU-As方式的FU indicator代替原來(lái)的NALU頭。 還有這個(gè)FU-As方式的頭好像是有兩個(gè)值,一個(gè)是FU indicator,另外一個(gè)是FU header,這兩個(gè)值我應(yīng)該填寫(xiě)什么?
按照我現(xiàn)在填寫(xiě)的內(nèi)容,VLC會(huì)出現(xiàn)解不出碼的情況,希望斑竹可以幫我回答的細(xì)致一點(diǎn)。謝謝了。 A:我覺(jué)得 RFC3984 上面說(shuō)得非常清楚啊。 首先你把一個(gè) NALU 的 EBSP 根據(jù)需求拆分為多個(gè)包,例如 3 個(gè),則:
第一個(gè) FU-A 包的 FU indicator 應(yīng)該是:F = NALU 頭中的 F;NRI = NALU 頭中的 NRI;Type = 28。FU header 應(yīng)該是:S = 1;E = 0;R = 0;Type = NALU 頭中的 Type。
第二個(gè) FU-A 包的 FU indicator 應(yīng)該是:F = NALU 頭中的 F;NRI = NALU 頭中的 NRI;Type = 28。FU header 應(yīng)該是:S = 0;E = 0;R = 0;Type = NALU 頭中的 Type。
第三個(gè) FU-A 包的 FU indicator 應(yīng)該是:F = NALU 頭中的 F;NRI = NALU 頭中的 NRI;Type = 28。FU header 應(yīng)該是:S = 0;E = 1;R = 0;Type = NALU 頭中的 Type。 Q:版主,我按照你的方式分好包發(fā)送了,發(fā)現(xiàn)VLC不會(huì)出現(xiàn)不能解幀的情況了,但是,還是出不來(lái)圖像。我想可能是因?yàn)榘l(fā)送序列參數(shù)集和圖像參數(shù)集的方法不對(duì),他們兩個(gè)的長(zhǎng)度都很小,只要一個(gè)包就可以了,我現(xiàn)在將他們按照singal NALU的方式發(fā)送,就是直接在NALU包前加一個(gè)RTP的頭,然后發(fā)出去。 是不是我這樣發(fā)參數(shù)集存在著問(wèn)題,反正我這邊VLC是解不了這個(gè)參數(shù)集,因?yàn)閰?shù)集解不了,所以下面的幀肯定解不了,所以出不了圖像。 麻煩版主再解釋一下如何發(fā)參數(shù)集。 A:今天剛接受了流媒體的相關(guān)培訓(xùn)。懂得看你的?? SDP 了。
對(duì)于你的問(wèn)題,不知道 SPS、PPS 打包是否有問(wèn)題。按照 RFC3984,而且感覺(jué)你打單一包的方式也是錯(cuò)的。我希望你能通過(guò)自己學(xué)習(xí)的方式去把這個(gè)問(wèn)題弄清楚,因?yàn)?RFC3984 里面說(shuō)得很清楚,請(qǐng)你自己學(xué)習(xí)學(xué)習(xí) RFC3984 吧。既然你在做這個(gè)工作,還是應(yīng)該仔細(xì)學(xué)習(xí)一下 RFC3984。
另外, SDP 中的 sprop-parameter-ets=Z0IACpZTBYmI 實(shí)際就是 SPS 和 PPS 的 BASE64 轉(zhuǎn)碼,你不用在碼流中再傳輸 SPS/PPS,直接從 SDP 就可以得到。 A2:1. SDP中已經(jīng)包括SPS&PPS,碼流中完全可以不用傳輸SPS&PPS 2. profile-level-id=42A01E,這是SPS的開(kāi)頭幾個(gè)字節(jié),剩下的在sprop-parameter-ets=Z0IACpZTBYmI, aMljiA==中,BASE64編碼,把“Z0IACpZTBYmI, aMljiA==”反BASE64轉(zhuǎn)換回去,應(yīng)該剛好是SPS&PPS的內(nèi)容 3. 打包注意,要求H.264碼流不是byte stream格式的,即沒(méi)有0x000001分隔,也沒(méi)有插入0x03,具體如何生成,檢查你的編碼器選項(xiàng)。 4. packetization-mode=1模式下,要求每個(gè)RTP中只有一個(gè)NAL單元,或者一個(gè)FU,不分段的NAL不做任何修改,直接作為RTP負(fù)載;分段的NAL注意,NAL頭不傳輸,有效負(fù)載從NAL頭之后開(kāi)始,根據(jù)NAL頭的信息生成FU的頭兩個(gè)字節(jié)(相當(dāng)于NAL頭拆為兩部分),具體生成方式版主已經(jīng)講得很清楚。 5. RTP的payload type要與SDP中一致,不然解的出才怪 |
總結(jié)
以上是生活随笔為你收集整理的关于H264通过RTP传输的打包方式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。