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ā)送,。 客戶端,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寫的是否正確。 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方式打包類型值為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àn)在填寫的內(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中一致,不然解的出才怪
|