牛逼的視頻會(huì)議網(wǎng)站:http://wmnmtm.blog.163.com/blog/#m=0
++++++++++++++++++++++++++++++++++++++++++++++++++++
http://wmnmtm.blog.163.com/blog/static/38245714201192491746701/
使用RTP傳輸H264的時(shí)候,需要用到sdp協(xié)議描述,其中有兩項(xiàng):Sequence Parameter Sets (SPS) 和Picture Parameter Set (PPS)需要用到,那么這兩項(xiàng)從哪里獲取呢?答案是從H264碼流中獲取.在H264碼流中,都是以"0x00 0x00 0x01"或者"0x00 0x00 0x00 0x01"為開始碼的,找到開始碼之后,使用開始碼之后的第一個(gè)字節(jié)的低5位判斷是否為7(sps)或者8(pps), 及data[4] & 0x1f == 7 || data[4] & 0x1f == 8.然后對(duì)獲取的nal去掉開始碼之后進(jìn)行base64編碼,得到的信息就可以用于sdp.sps和pps需要用逗號(hào)分隔開來.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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編碼形式的,不容易理解,附件有一個(gè)工具軟件可以對(duì)SDP中的SPS和PPS進(jìn)行解析。用法是在命令行中輸入: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 = 0Start 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/////////////////////////////////////////////////////////////////////////////////////////////////這里需要特別提一下這兩個(gè)參數(shù)pic_width_in_mbs_minus1 = 21 pic_height_in_mbs_minus1 = 17分別表示圖像的寬和高,以宏塊(16x16)為單位的值減1因此,實(shí)際的寬為 (21+1)*16 = 352
spsparser.rar
http://krdai.info.sixxs.org/blog/mp4-sps-pps-data.html
最近在做跟 h264 encode/decode 相關(guān)的研究,目標(biāo)是希望可以從 Android 的 MediaRecorder 當(dāng)中取出 h264 的資訊。目前問題是在於 SPS 以及 PPS 到底要怎樣得到。由於 MediaRecorder 是寫入 mp4 檔案中,所以不得已只好來去分析一下 mp4 的檔案格式,發(fā)現(xiàn)沒有想像中的困難. 主要是參照 ISO/IEC 14496-15 這部份. 在 mp4 的檔案之中, 找到 avcC 這個(gè)字串, 之後就是接上 AVCDecoderConfigurationRecord. AVCDecoderConfigurationRecord 的 format 如下:
[cpp] view plaincopyaligned(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(8*sequenceParameterSetLength) sequenceParameterSetNALUnit; } unsigned int(8) numOfPictureParameterSets; for (i=0; i< numOfPictureParameterSets; i++) { unsigned int(16) pictureParameterSetLength; bit(8*pictureParameterSetLength) pictureParameterSetNALUnit; } }對(duì)照一下這樣就可以找到 SPS 和 PPS
+++++++++++++++++++++++++++++++++++++++++++++vlc沒有收到pps和sps2010-10-08 16:16問題 packetizer_h264 packetizer warning: waiting for SPS/PPS是因?yàn)榻獯a器只是在第一次執(zhí)行編碼的時(shí)候,才編碼出 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] |
如何用C語(yǔ)言取出H.264ES文件里的nal(sps,pps)信息。比如width, height, profile等等請(qǐng)高手指點(diǎn)指點(diǎn)。。。 http://www.oschina.net/question/225813_35707
解析sps,pps的代碼在ffmpeg里面就有, 抄出來就行了, 我以前也自己寫過...ffmpeg的libavcodec/h264_parser.c,h264_ps.c函數(shù)ff_h264_decode_seq_parameter_setff_h264_decode_picture_parameter_set自己可以看代碼.
H264參數(shù)語(yǔ)法文檔: SPS、PPS、IDR http://blog.csdn.net/heanyu/article/details/6205390H.264碼流第一個(gè) NALU 是 SPS(序列參數(shù)集Sequence Parameter Set)對(duì)應(yīng)H264標(biāo)準(zhǔn)文檔 7.3.2.1 序列參數(shù)集的語(yǔ)法進(jìn)行解析
|字號(hào) 訂閱
Q:現(xiàn)在小弟初次嘗試H264的編碼通過RTP方式傳輸,具體實(shí)驗(yàn)環(huán)境的問題如下:環(huán)境:服務(wù)器端,H264的幀數(shù)據(jù)(可能超過64k),分成N個(gè)1460字節(jié)的包,然后加上RTP頭發(fā)送。客戶端,VLC播放器,通過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ù)幀可能超過64k,所以忘大蝦們能夠仔細(xì)解釋一下對(duì)于小弟這種情況下的RTP傳輸)
A:我覺得所有的問題在 RFC3984 里面都已經(jīng)說得很清楚了。不知道你有哪點(diǎn)不懂,請(qǐng)具體提出來。
Q:斑竹好,我這邊是用VLC和服務(wù)器端進(jìn)行通訊的,他們是用RTSP協(xié)議建立 開始時(shí)的連接的,服務(wù)器返回DISCRIBERS請(qǐng)求的SDP和下面描述的相同,我使用的packetization-mode=1,即FU-As方式打 包,因?yàn)槲疫@邊上來的數(shù)據(jù)幀可能超過64k數(shù)據(jù)。能否麻煩斑竹看看我這邊的SDP寫的是否正確。SDP:v=0o=- 1 1 IN IP4 127.0.0.1s=VStream Livea=type:broadcastt=0 0c=IN IP4 0.0.0.0m=video 49170 RTP/AVP 99a=rtpmap:99 H264/90000a=fmtp:99 profile-level-id=42A01E; packetization-mode=1; sprop-parameter-ets=Z0IACpZTBYmI, aMljiA==a=control:trackID=0還有就是在RTP發(fā)送時(shí),我打好包的數(shù)據(jù)方式如下面所示:上來的幀數(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上面說的好像和我現(xiàn)在的有點(diǎn)不 同,RFC3984上面說FU-As方式打包類型值為28,我不知道這個(gè)是否十進(jìn)制的,如果按照RFC3984上說的NALU頭應(yīng)該是多少?還是用FU- As方式的FU indicator代替原來的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:我覺得 RFC3984 上面說得非常清楚啊。首先你把一個(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)不能解幀的情況了, 但是,還是出不來圖像。我想可能是因?yàn)榘l(fā)送序列參數(shù)集和圖像參數(shù)集的方法不對(duì),他們兩個(gè)的長(zhǎng)度都很小,只要一個(gè)包就可以了,我現(xiàn)在將他們按照singal NALU的方式發(fā)送,就是直接在NALU包前加一個(gè)RTP的頭,然后發(fā)出去。是不是我這樣發(fā)參數(shù)集存在著問題,反正我這邊VLC是解不了這個(gè)參數(shù)集,因?yàn)閰?shù)集解不了,所以下面的幀肯定解不了,所以出不了圖像。麻煩版主再解釋一下如何發(fā)參數(shù)集。
A:今天剛接受了流媒體的相關(guān)培訓(xùn)。懂得看你的 SDP 了。對(duì) 于你的問題,不知道 SPS、PPS 打包是否有問題。按照 RFC3984,而且感覺你打單一包的方式也是錯(cuò)的。我希望你能通過自己學(xué)習(xí)的方式去把這個(gè)問題弄清楚,因?yàn)?RFC3984 里面說得很清楚,請(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&PPS2. profile-level-id=42A01E,這是SPS的開頭幾個(gè)字節(jié),剩下的在sprop-parameter- ets=Z0IACpZTBYmI, aMljiA==中,BASE64編碼,把“Z0IACpZTBYmI, aMljiA==”反BASE64轉(zhuǎn)換回去,應(yīng)該剛好是SPS&PPS的內(nèi)容3. 打包注意,要求H.264碼流不是byte stream格式的,即沒有0x000001分隔,也沒有插入0x03,具體如何生成,檢查你的編碼器選項(xiàng)。4. packetization-mode=1模式下,要求每個(gè)RTP中只有一個(gè)NAL單元,或者一個(gè)FU,不分段的NAL不做任何修改,直接作為RTP負(fù) 載;分段的NAL注意,NAL頭不傳輸,有效負(fù)載從NAL頭之后開始,根據(jù)NAL頭的信息生成FU的頭兩個(gè)字節(jié)(相當(dāng)于NAL頭拆為兩部分),具體生成方 式版主已經(jīng)講得很清楚。5. RTP的payload type要與SDP中一致,不然解的出才怪
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注