H264中的sps pps

使用RTP傳輸H264的時候,需要用到sdp協(xié)議描述,其中有兩項:Sequence Parameter Sets (SPS) 和Picture Parameter Set (PPS)需要用到,那么這兩項從哪里獲取呢?答案是從H264碼流中獲取.在H264碼流中,都是以"0x00 0x00 0x01"或者"0x00 0x00 0x00 0x01"為開始碼的,找到開始碼之后,使用開始碼之后的第一個字節(jié)的低5位判斷是否為7(sps)或者8(pps), 及data[4] & 0x1f == 7 || data[4] & 0x1f == 8.然后對獲取的nal去掉開始碼之后進行base64編碼,得到的信息就可以用于sdp.sps和pps需要用逗號分隔開來.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
如何解析SDP中包含的H.264的SPS和PPS串
http://www.pernet.tv.sixxs.org/thread-109-1-1.html
SDP中的H.264的SPS和PPS串萤厅,包含了初始化H.264解碼器所需要的信息參數(shù)伞矩,包括編碼所用的profile,level它褪,圖像的寬和高鬼癣,deblock濾波器等陶贼。
由于SDP中的SPS和PPS都是BASE64編碼形式的,不容易理解待秃,附件有一個工具軟件可以對SDP中的SPS和PPS進行解析拜秧。
用法是在命令行中輸入:
spsparser sps.txt pps.txt output.txt

例如sps.txt中的內(nèi)容為:
Z0LgFNoFglE=
pps.txt中的內(nèi)容為:
aM4wpIA=

最終解析的到的結(jié)果為:

Start dumping SPS:
profile_idc = 66
constrained_set0_flag = 1
constrained_set1_flag = 1
constrained_set2_flag = 1
constrained_set3_flag = 0
level_idc = 20
seq_parameter_set_id = 0
chroma_format_idc = 1
bit_depth_luma_minus8 = 0
bit_depth_chroma_minus8 = 0
seq_scaling_matrix_present_flag = 0
log2_max_frame_num_minus4 = 0
pic_order_cnt_type = 2
log2_max_pic_order_cnt_lsb_minus4 = 0
delta_pic_order_always_zero_flag = 0
offset_for_non_ref_pic = 0
offset_for_top_to_bottom_field = 0
num_ref_frames_in_pic_order_cnt_cycle = 0
num_ref_frames = 1
gaps_in_frame_num_value_allowed_flag = 0
pic_width_in_mbs_minus1 = 21
pic_height_in_mbs_minus1 = 17
frame_mbs_only_flag = 1
mb_adaptive_frame_field_flag = 0
direct_8x8_interence_flag = 0
frame_cropping_flag = 0
frame_cropping_rect_left_offset = 0
frame_cropping_rect_right_offset = 0
frame_cropping_rect_top_offset = 0
frame_cropping_rect_bottom_offset = 0
vui_parameters_present_flag = 0

Start dumping PPS:
pic_parameter_set_id = 0
seq_parameter_set_id = 0
entropy_coding_mode_flag = 0
pic_order_present_flag = 0
num_slice_groups_minus1 = 0
slice_group_map_type = 0
num_ref_idx_l0_active_minus1 = 0
num_ref_idx_l1_active_minus1 = 0
weighted_pref_flag = 0
weighted_bipred_idc = 0
pic_init_qp_minus26 = 0
pic_init_qs_minus26 = 0
chroma_qp_index_offset = 10
deblocking_filter_control_present_flag = 1
constrained_intra_pred_flag = 0
redundant_pic_cnt_present_flag = 0
transform_8x8_mode_flag = 0
pic_scaling_matrix_present_flag = 0
second_chroma_qp_index_offset = 10

/////////////////////////////////////////////////////////////////////////////////////////////////
這里需要特別提一下這兩個參數(shù)
pic_width_in_mbs_minus1 = 21
pic_height_in_mbs_minus1 = 17
分別表示圖像的寬和高,以宏塊(16x16)為單位的值減1
因此章郁,實際的寬為 (21+1)*16 = 352
spsparser.rar
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
http://krdai.info.sixxs.org/blog/mp4-sps-pps-data.html

最近在做跟 h264 encode/decode 相關的研究枉氮,目標是希望可以從 Android 的 MediaRecorder 當中取出 h264 的資訊。目前問題是在於 SPS 以及 PPS 到底要怎樣得到暖庄。由於 MediaRecorder 是寫入 mp4 檔案中聊替,所以不得已只好來去分析一下 mp4 的檔案格式,發(fā)現(xiàn)沒有想像中的困難. 主要是參照 ISO/IEC 14496-15 這部份. 在 mp4 的檔案之中, 找到 avcC 這個字串, 之後就是接上 AVCDecoderConfigurationRecord. AVCDecoderConfigurationRecord 的 format 如下:

[cpp] view plaincopy
aligned(8) class AVCDecoderConfigurationRecord {
unsigned int(8) configurationVersion = 1;
unsigned int(8) AVCProfileIndication;
unsigned int(8) profile_compatibility;
unsigned int(8) AVCLevelIndication;

bit(6) reserved = '111111'b;
unsigned int(2) lengthSizeMinusOne;

bit(3) reserved = '111'b;
unsigned int(5) numOfSequenceParameterSets;

for (i=0; i< numOfSequenceParameterSets; i++) {
unsigned int(16) sequenceParameterSetLength ;
bit(8sequenceParameterSetLength) sequenceParameterSetNALUnit;
}
unsigned int(8) numOfPictureParameterSets;
for (i=0; i< numOfPictureParameterSets; i++) {
unsigned int(16) pictureParameterSetLength;
bit(8
pictureParameterSetLength) pictureParameterSetNALUnit;
}
}

對照一下這樣就可以找到 SPS 和 PPS

+++++++++++++++++++++++++++++++++++++++++++++

vlc沒有收到pps和sps
2010-10-08 16:16
問題 packetizer_h264 packetizer warning: waiting for SPS/PPS

是因為解碼器只是在第一次執(zhí)行編碼的時候培廓,才編碼出 SPS惹悄、PPS、和I_Frame肩钠;
h264 packetizer has set so, that it sends sps/pps only first keyframe,
I'm trying to figure what breaks if that is changed so sps/pps is written in every keyframe.
[出自| http://trac.videolan.org/vlc/ticket/1384]
解決辦法:
1泣港、編碼器編碼出每個關鍵幀都加上SPS、PPS 价匠,據(jù)說通常情況編碼器編出的 SPS当纱、PPS是一樣的,所以這種方法耗費資源踩窖。
2坡氯、在服務器接收到客戶端請求時,發(fā)送第一個package 加上 SPS毙石、PPS廉沮。
具體如下:
1、在 VideoOpenFileSource 添加一個變量 isFirstFrame徐矩;
2、構(gòu)造時初始化 isFirstFrame = true;
3叁幢、在int VideoOpenFileSource::readFromBufferChain() 修改如下:
1 if(isFirstFrame == true)
2 {
3 memcpy(fTo, h264_header, sizeof(h264_header)); /* h264_header = pps +sps*/
4 offset = sizeof(h264_header);
5 framesize = BufferChain_get(fInput.video_bufs, fTo + offset);
6 offset += framesize;
7 isFirstFrame = false;
8 printf("this is the first fime\n");
9 sleep(1);
10 }
11 else
12 {
13 framesize = BufferChain_get(fInput.video_bufs, fTo + offset);
14 offset += framesize;
15 }
1
[http://topic.csdn.net/u/20100801/17/ef35e664-92ff-4144-a35f-3984dcf11da3.html| 參考]

========================================================================
sdp 關于pps和sps的疑問:
packetization-mode 主要是定義包的模式滤灯,單一 NALU單元模式(0);非交錯(non-interleaved)封包模式(1);交錯(interleaved)封包模式(2)
sprop-parameter-sets 等于H.264 的序列參數(shù)集和圖像參數(shù) NAL單元鳞骤,base64轉(zhuǎn)換窒百;(即= sps+pps)
profile-level-id 這個參數(shù)用于指示 H.264 流的 profile 類型和級別。這知道這個是啥東東

參考 黑暗長老 www.cppblog.com/czanyou/
ffmpeg decode 關于pps sps問題:
stackoverflow.com/questions/3493742/problem-to-decode-h264-video-over-rtp-with-ffmpeg-libavcodec/3500432#3500432

如何用C語言取出H.264ES文件里的nal(sps,pps)信息豫尽。比如width, height, profile等等

請高手指點指點篙梢。。美旧。 http://www.oschina.net/question/225813_35707
解析sps,pps的代碼在ffmpeg里面就有, 抄出來就行了, 我以前也自己寫過...
ffmpeg的libavcodec/h264_parser.c,
h264_ps.c
函數(shù)
ff_h264_decode_seq_parameter_set
ff_h264_decode_picture_parameter_set
自己可以看代碼.

H264參數(shù)語法文檔: SPS渤滞、PPS、IDR http://blog.csdn.net/heanyu/article/details/6205390

H.264碼流第一個 NALU 是 SPS(序列參數(shù)集Sequence Parameter Set)
對應H264標準文檔 7.3.2.1 序列參數(shù)集的語法進行解析

關于H264通過RTP傳輸?shù)拇虬绞?/p>

|字號 訂閱

Q:現(xiàn)在小弟初次嘗試H264的編碼通過RTP方式傳輸榴嗅,具體實驗環(huán)境的問題如下:
環(huán)境:
服務器端妄呕,H264的幀數(shù)據(jù)(可能超過64k),分成N個1460字節(jié)的包嗽测,然后加上RTP頭發(fā)送绪励。
客戶端,VLC播放器唠粥,通過RTSP協(xié)議建立連接疏魏,然后接收數(shù)據(jù)解碼播放。
結(jié)果:
VLC不能解碼接收到的數(shù)據(jù)晤愧,解碼出錯大莫,VLC的信息中顯示不能解碼幀數(shù)據(jù)。
我已經(jīng)閱讀了一遍rfc3984的文檔养涮,對里面的如何進行打包和用rtp傳輸不是非常理解葵硕,希望各位大蝦能夠幫小弟一把,告訴小弟這些和H264的幀該如何發(fā)送贯吓,該如何分包懈凹,該如何加頭信息等等。
(其中看到FUs的方式好像適合分包發(fā)送悄谐,因為小弟的數(shù)據(jù)幀可能超過64k介评,所以忘大蝦們能夠仔細解釋一下對于小弟這種情況下的RTP傳輸)

A:我覺得所有的問題在 RFC3984 里面都已經(jīng)說得很清楚了。不知道你有哪點不懂爬舰,請具體提出來们陆。

Q:斑竹好,我這邊是用VLC和服務器端進行通訊的情屹,他們是用RTSP協(xié)議建立 開始時的連接的坪仇,服務器返回DISCRIBERS請求的SDP和下面描述的相同,我使用的packetization-mode=1垃你,即FU-As方式打 包椅文,因為我這邊上來的數(shù)據(jù)幀可能超過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ù)據(jù)方式如下面所示:
上來的幀數(shù)據(jù)為:NALU頭+EBSP數(shù)據(jù)
因為幀數(shù)據(jù)大于1460字節(jié)少辣,所以我把數(shù)據(jù)分為N個不大于1460字節(jié)的包,每個包前面加上RTP頭發(fā)出去羡蛾。
其 中NALU頭的數(shù)值I幀為0x65漓帅,參數(shù)集為0x67和0x68,這個值是不是有點錯誤痴怨,我看RFC3984上面說的好像和我現(xiàn)在的有點不 同忙干,RFC3984上面說FU-As方式打包類型值為28,我不知道這個是否十進制的腿箩,如果按照RFC3984上說的NALU頭應該是多少豪直?還是用FU- As方式的FU indicator代替原來的NALU頭。
還有這個FU-As方式的頭好像是有兩個值珠移,一個是FU indicator弓乙,另外一個是FU header,這兩個值我應該填寫什么钧惧?

按照我現(xiàn)在填寫的內(nèi)容暇韧,VLC會出現(xiàn)解不出碼的情況,希望斑竹可以幫我回答的細致一點浓瞪。謝謝了懈玻。

A:我覺得 RFC3984 上面說得非常清楚啊。
首先你把一個 NALU 的 EBSP 根據(jù)需求拆分為多個包乾颁,例如 3 個涂乌,則:

第一個 FU-A 包的 FU indicator 應該是:F = NALU 頭中的 F;NRI = NALU 頭中的 NRI英岭;Type = 28湾盒。FU header 應該是:S = 1;E = 0诅妹;R = 0罚勾;Type = NALU 頭中的 Type。

第二個 FU-A 包的 FU indicator 應該是:F = NALU 頭中的 F吭狡;NRI = NALU 頭中的 NRI尖殃;Type = 28。FU header 應該是:S = 0划煮;E = 0送丰;R = 0;Type = NALU 頭中的 Type弛秋。

第三個 FU-A 包的 FU indicator 應該是:F = NALU 頭中的 F蚪战;NRI = NALU 頭中的 NRI牵现;Type = 28铐懊。FU header 應該是:S = 0邀桑;E = 1;R = 0科乎;Type = NALU 頭中的 Type壁畸。

Q:版主,我按照你的方式分好包發(fā)送了茅茂,發(fā)現(xiàn)VLC不會出現(xiàn)不能解幀的情況了捏萍, 但是,還是出不來圖像空闲。我想可能是因為發(fā)送序列參數(shù)集和圖像參數(shù)集的方法不對令杈,他們兩個的長度都很小,只要一個包就可以了碴倾,我現(xiàn)在將他們按照singal NALU的方式發(fā)送逗噩,就是直接在NALU包前加一個RTP的頭,然后發(fā)出去跌榔。
是不是我這樣發(fā)參數(shù)集存在著問題异雁,反正我這邊VLC是解不了這個參數(shù)集,因為參數(shù)集解不了僧须,所以下面的幀肯定解不了纲刀,所以出不了圖像。
麻煩版主再解釋一下如何發(fā)參數(shù)集担平。

A:今天剛接受了流媒體的相關培訓示绊。懂得看你的 SDP 了。

對 于你的問題暂论,不知道 SPS面褐、PPS 打包是否有問題。按照 RFC3984空另,而且感覺你打單一包的方式也是錯的盆耽。我希望你能通過自己學習的方式去把這個問題弄清楚,因為 RFC3984 里面說得很清楚扼菠,請你自己學習學習 RFC3984 吧摄杂。既然你在做這個工作,還是應該仔細學習一下 RFC3984循榆。

另外析恢, SDP 中的 sprop-parameter-ets=Z0IACpZTBYmI 實際就是 SPS 和 PPS 的 BASE64 轉(zhuǎn)碼,你不用在碼流中再傳輸 SPS/PPS秧饮,直接從 SDP 就可以得到映挂。

A2:1.SDP中已經(jīng)包括SPS&PPS泽篮,碼流中完全可以不用傳輸SPS&PPS

  1. profile-level-id=42A01E,這是SPS的開頭幾個字節(jié)柑船,剩下的在sprop-parameter- ets=Z0IACpZTBYmI, aMljiA==中帽撑,BASE64編碼,把“Z0IACpZTBYmI, aMljiA==”反BASE64轉(zhuǎn)換回去鞍时,應該剛好是SPS&PPS的內(nèi)容
  2. 打包注意亏拉,要求H.264碼流不是byte stream格式的,即沒有0x000001分隔逆巍,也沒有插入0x03及塘,具體如何生成,檢查你的編碼器選項锐极。
  3. packetization-mode=1模式下笙僚,要求每個RTP中只有一個NAL單元,或者一個FU灵再,不分段的NAL不做任何修改肋层,直接作為RTP負 載;分段的NAL注意檬嘀,NAL頭不傳輸槽驶,有效負載從NAL頭之后開始,根據(jù)NAL頭的信息生成FU的頭兩個字節(jié)(相當于NAL頭拆為兩部分)鸳兽,具體生成方 式版主已經(jīng)講得很清楚掂铐。
  4. RTP的payload type要與SDP中一致,不然解的出才怪
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末揍异,一起剝皮案震驚了整個濱河市全陨,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌衷掷,老刑警劉巖辱姨,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異戚嗅,居然都是意外死亡雨涛,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進店門懦胞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來替久,“玉大人,你說我怎么就攤上這事躏尉◎歉” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵胀糜,是天一觀的道長颅拦。 經(jīng)常有香客問我蒂誉,道長,這世上最難降的妖魔是什么距帅? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任右锨,我火速辦了婚禮,結(jié)果婚禮上锥债,老公的妹妹穿的比我還像新娘陡蝇。我一直安慰自己,他們只是感情好哮肚,可當我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著广匙,像睡著了一般允趟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鸦致,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天藏畅,我揣著相機與錄音咖摹,去河邊找鬼。 笑死,一個胖子當著我的面吹牛隙弛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播复哆,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼歧沪,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了折砸?” 一聲冷哼從身側(cè)響起看疗,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎睦授,沒想到半個月后两芳,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡去枷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年怖辆,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片删顶。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡竖螃,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出翼闹,到底是詐尸還是另有隱情斑鼻,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布猎荠,位于F島的核電站坚弱,受9級特大地震影響蜀备,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜荒叶,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一碾阁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧些楣,春花似錦脂凶、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至鹅很,卻和暖如春嘶居,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背促煮。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工邮屁, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人菠齿。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓佑吝,卻偏偏與公主長得像,于是被迫代替她去往敵國和親绳匀。 傳聞我的和親對象是個殘疾皇子芋忿,可洞房花燭夜當晚...
    茶點故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容