[feat] gb28181: 一部分解析ps流的代码,进行中

pull/141/head
q191201771 3 years ago
parent 9969144c89
commit 66b3baff51

@ -0,0 +1,276 @@
package gb28181
import (
"encoding/hex"
"github.com/q191201771/lal/pkg/avc"
"github.com/q191201771/naza/pkg/bele"
"github.com/q191201771/naza/pkg/nazabits"
"github.com/q191201771/naza/pkg/nazabytes"
"github.com/q191201771/naza/pkg/nazalog"
)
const (
psPackStartCodePackHeader = 0x01ba
psPackStartCodeSystemHeader = 0x01bb
psPackStartCodeProgramStreamMap = 0x01bc
psPackStartCodeAudioStream = 0x01c0
psPackStartCodeVideoStream = 0x01e0
)
type onAudioFn func(payload []byte, dts int64, pts int64)
type onVideoFn func(payload []byte, dts int64, pts int64)
type IPsUnpackerObserver interface {
OnAudio(payload []byte, dts int64, pts int64)
// OnVideo
//
// @param payload: annexb格式
//
OnVideo(payload []byte, dts int64, pts int64)
}
// PsUnpacker 解析ps(Progream Stream)流
//
type PsUnpacker struct {
buf *nazabytes.Buffer
onAudio onAudioFn
onVideo onVideoFn
}
func NewPsUnpacker() *PsUnpacker {
return &PsUnpacker{
buf: nazabytes.NewBuffer(4096),
}
}
func (p *PsUnpacker) WithObserver(obs IPsUnpackerObserver) *PsUnpacker {
p.onAudio = obs.OnAudio
p.onVideo = obs.OnVideo
return p
}
func (p *PsUnpacker) WithCallbackFunc(onAudio onAudioFn, onVideo onVideoFn) *PsUnpacker {
p.onAudio = onAudio
p.onVideo = onVideo
return p
}
// FeedRtpPacket
//
// @param rtpPacket: rtp包注意包含rtp包头部分
//
func (p *PsUnpacker) FeedRtpPacket(rtpPacket []byte) {
nazalog.Debugf("> FeedRtpPacket. len=%d", len(rtpPacket))
// skip rtp header
p.FeedRtpBody(rtpPacket[12:])
}
func (p *PsUnpacker) FeedRtpBody(rtpBody []byte) {
_, _ = p.buf.Write(rtpBody)
// ISO/IEC iso13818-1
//
// 2.5 Program Stream bitstream requirements
//
// 2.5.3.3 Pack layer of Program Stream
// Table 2-33 - Program Stream pack header
//
// 2.5.3.5 System header
// Table 2-32 - Program Stream system header
//
// 2.5.4 Program Stream map
// Table 2-35 - Program Stream map
//
// TODO(chef): [fix] 有些没做有效长度判断
for p.buf.Len() != 0 {
rb := p.buf.Bytes()
i := 0
code := bele.BeUint32(rb[i:])
i += 4
switch code {
case psPackStartCodePackHeader:
nazalog.Debugf("-----pack header-----")
// skip system clock reference(SCR)
// skip PES program mux rate
i += 6 + 3
// skip stuffing
l := int(rb[i] & 0x7)
i += 1 + l
p.buf.Skip(i)
case psPackStartCodeSystemHeader:
nazalog.Debugf("-----system header-----")
// skip
l := int(bele.BeUint16(rb[i:]))
p.buf.Skip(i + 2 + l)
case psPackStartCodeProgramStreamMap:
nazalog.Debugf("-----program stream map-----")
if len(rb[i:]) < 6 {
return
}
// skip program_stream_map_length
// skip current_next_indicator
// skip reserved
// skip program_stream_map_version
// skip reverved
// skip marked_bit
i += 4 // 2 + 1 + 1
// program_stream_info_length
l := int(bele.BeUint16(rb[i:]))
i += 2
if len(rb[i:]) < l+2 {
return
}
i += l
// elementary_stream_map_length
esml := int(bele.BeUint16(rb[i:]))
nazalog.Debugf("l=%d, esml=%d", l, esml)
i += 2
if len(rb[i:]) < esml+4 {
return
}
for esml > 0 {
streamType := rb[i]
i += 1
streamId := rb[i]
i += 1
// elementary_stream_info_length
esil := int(bele.BeUint16(rb[i:]))
nazalog.Debugf("streamType=%d, streamId=%d, esil=%d", streamType, streamId, esil)
i += 2 + esil
esml = esml - 4 - esil
}
// skip
i += 4
nazalog.Debugf("CHEFERASEME i=%d, esml=%d, %s", i, esml, hex.Dump(nazabytes.Prefix(p.buf.Bytes(), 128)))
p.buf.Skip(i)
case psPackStartCodeAudioStream:
nazalog.Debugf("-----audio stream-----")
case psPackStartCodeVideoStream:
nazalog.Debugf("-----video stream-----")
length := int(bele.BeUint16(rb[i:]))
i += 2
//nazalog.Debugf("CHEFERASEME %d %d %d", p.buf.Len(), len(rtpBody), length)
if len(rb)-6 < length {
return
}
ptsDtsFlag := rb[i+1] & 0x0c
phdl := int(rb[i+2])
i += 3
var pts uint64
var dts uint64
j := 0
if ptsDtsFlag&0x2 != 0 {
_, pts = readPts(rb[i:])
j += 5
}
if ptsDtsFlag&0x1 != 0 {
_, dts = readPts(rtpBody[i+j:])
} else {
dts = pts
}
i += phdl
nazalog.Debugf("code=%d, length=%d, ptsDtsFlag=%d, phdl=%d, pts=%d, dts=%d, type=%s", code, length, ptsDtsFlag, phdl, pts, dts, avc.ParseNaluTypeReadable(rb[i+4]))
if p.onVideo != nil {
p.onVideo(rb[i:i+length-3-phdl], int64(dts), int64(pts))
}
p.buf.Skip(6 + length)
default:
nazalog.Errorf("%s", hex.Dump(nazabytes.Prefix(rb, 32)))
return
}
}
}
// ---------------------------------------------------------------------------------------------------------------------
// TODO(chef): [refactor] 以下代码拷贝来自package mpegts重复了
// Pes -----------------------------------------------------------
// <iso13818-1.pdf>
// <2.4.3.6 PES packet> <page 49/174>
// <Table E.1 - PES packet header example> <page 142/174>
// <F.0.2 PES packet> <page 144/174>
// packet_start_code_prefix [24b] *** always 0x00, 0x00, 0x01
// stream_id [8b] *
// PES_packet_length [16b] **
// '10' [2b]
// PES_scrambling_control [2b]
// PES_priority [1b]
// data_alignment_indicator [1b]
// copyright [1b]
// original_or_copy [1b] *
// PTS_DTS_flags [2b]
// ESCR_flag [1b]
// ES_rate_flag [1b]
// DSM_trick_mode_flag [1b]
// additional_copy_info_flag [1b]
// PES_CRC_flag [1b]
// PES_extension_flag [1b] *
// PES_header_data_length [8b] *
// -----------------------------------------------------------
type Pes struct {
pscp uint32
sid uint8
ppl uint16
pad1 uint8
ptsDtsFlag uint8
pad2 uint8
phdl uint8
pts uint64
dts uint64
}
func ParsePes(b []byte) (pes Pes, length int) {
br := nazabits.NewBitReader(b)
//pes.pscp, _ = br.ReadBits32(24)
//pes.sid, _ = br.ReadBits8(8)
//pes.ppl, _ = br.ReadBits16(16)
pes.pad1, _ = br.ReadBits8(8)
pes.ptsDtsFlag, _ = br.ReadBits8(2)
pes.pad2, _ = br.ReadBits8(6)
pes.phdl, _ = br.ReadBits8(8)
_, _ = br.ReadBytes(uint(pes.phdl))
length = 9 + int(pes.phdl)
// 处理得不是特别标准
if pes.ptsDtsFlag&0x2 != 0 {
_, pes.pts = readPts(b[9:])
}
if pes.ptsDtsFlag&0x1 != 0 {
_, pes.dts = readPts(b[14:])
} else {
pes.dts = pes.pts
}
//pes.pts = (pes.pts - delay) / 90
//pes.dts = (pes.dts - delay) / 90
return
}
// read pts or dts
func readPts(b []byte) (fb uint8, pts uint64) {
fb = b[0] >> 4
pts |= uint64((b[0]>>1)&0x07) << 30
pts |= (uint64(b[1])<<8 | uint64(b[2])) >> 1 << 15
pts |= (uint64(b[3])<<8 | uint64(b[4])) >> 1
return
}

@ -0,0 +1,133 @@
package gb28181_test
import (
"bytes"
"encoding/hex"
"fmt"
"github.com/q191201771/lal/pkg/avc"
"github.com/q191201771/lal/pkg/gb28181"
"github.com/q191201771/naza/pkg/nazabytes"
"github.com/q191201771/naza/pkg/nazalog"
"io/ioutil"
"os"
"testing"
)
var goldenRtpList = []string{
// 00 00 01 e0 类型code
// 11 02 长度
// 8c padding
// 80 pts dts flag
// 09 长度
// 25 e2 5f e0 39 pts
// 没有dts
// ff ff ff f8 跳过
//
// 00 00 01 e0 11 02 8c 80 09 25 e2 5f e0 39 ff ff
// ff f8 00 00 00 01 01 e0 b1 ff c5 f3 39 24 78 bb
//
// length = 4354
// 1: 1380 (1400 - 20)
// 2: 1400 = 2780
// 3: 1400 = 4180
// 4: 180 = 4360
// = 2800+1560=4360
// 2980
// 1374
//// ----------
//// 1454 -> 1412 -> 1400
//"8060000000000e100bebc265000001ba57897f80e401028f63feffff02503cb0000001e011028c800925e25fe039fffffff80000000101e0b1ffc5f3392478bb4db7bf9b7a9cbfdeea7c266cbec2e91ce607c147339fbc253aa841dfc29d8a910d9d5486758d473b1b8eea14652a06e8a9de78934189a7d84f10b9bc5bcfdc2f37708e51d4664c25ff477dd92e97cac60c4dc370027dc3ace5da4f10b43151421074a36ebb195b3ef557d596ca5ede7b304ecd0754edef9b4211ba09593f1dd1babe9d214e2d371f90f9ef5ced692c18bd7312cf98766b5bf254315efa15b6f68722331fb8ec80cde0b008463748ef27a1b51692672ced427086c951b03983ce960ef09a720e2930bcdec16731d19120153ad49311959a94a4cf69f32a206b988a4de23cfa2e3886a5f7e8d944ac85afab5f96622fbc902de2e12f4778cbfe72d79ff3766b4629ee67883644c7dd4d9a4ad05144f294b020bff4d66f25edfa6ebd1fc3650244fa48c15c67751189176297bdc9e10339fc3640492b9a857873a65b5e4eef8fddf394bcb46894235a8c52ea73b2e153a5ac894baeb85f399bd9bc214d70c5d3afeefe5aab0abf7e906a743d94ff46ea4624858f147cad41914aa634c7d4737b4a48b682e3d310535209df8c0953f72c2ff363a2076380abdb33b486399ea05cae58632e84f74ba54873183e02249064545e033b8c3126a0689fe09b9a9f8036f9c0fa9a22c8f36fdfde08a4290dae15bff0a4ac8b36653fea9e93df52eeb50db4e0c95c088302d59d4c9249e59a0753ec0618bed5c8160cc3b6c5765b8c54fe82cf41aa9e6196ea899ae2bee831342eba94c0cfbfef24eddcbe8d6ca45faf5edb7abec5f6ff7d834416ef6f8ffc27c52f082bc2fdfe05d22911e91b2f04ab342c19cd40c1c66028da056545ce7194f4e20519e60d9317e74189ac43542edcc557525b92f20660d56710ceeb9c2f380bdf83938d871968f1ef4e06b04b049e56c985fd6e825fef01e19e1197f5c3d1f3d9ce11724b25a7fbb16441daa01e0297a25afd237390c8ff3042d500fd642b5be1204ac7205a42ae81a1273ea265479d1806673c7623b330cc4f98b46ed957f1d4dfc99a56930e30c44d3d72f88f4d872d8260c5d875459555d5f4788a10e642210552e62a2cddb8cd320a3cd37115585820fcc07d6684b854a57db4ed7bc52e49d1649479db5d887d4357d7f4f98e9edb7855c88dbc1e6db59d7eb607fb9fb5800c066f6769eefb26f9cafddafa493b7931d9322fc6d8090b919784017c4dee418c676efd8cbe6fdff782f1b52a73b714a8fac2ef4667c70323c194b5cd25bf7076d5daef39c6ec51619a6c0fc9ef412cebf1ab84bc7fd0985da9fe8d160d466c0ca2a382eaca9c312c6db1db20021c86704cb1d2deb8f14180964a812cfb41d1d4cc8731e60ab42c99767f5725413c97bd5e9cfb3b0ecab385efdf6907888470600427c634755877256c8e416a5c2b61dd918959afcd79f87f0327195c2eae0756294db92f50fbc7bcefb8b5fd3ba0f9ca7c07fcc84731f42fb48d6ffaf4e11c71519e87098d6b92a572b34f1827da03d913763a60074022aa8e1f60c0bf731394624fac314d52b69f3d3ca0a431c1d5bd3f4edba6af4d9325d1e46785205217d97848ff6d3f4023bef8db627a155792c86a5cdc5459a98ec06779c881c9dbc67a933f109baed085c488097fb4ad43c1c22336fa8285b55bfda8f285507387e2cec703b7fc2e6f3c88f17c382c51c641c6ba8d4ae8523b2f7569153ed449da538a8c84c3e7a674332f670976cff9eba03d75961b1f35ef0091438f701708b30157e3a0a4bcdbaee46cbbe65dd1d614b5b526ab1d979ebd4cbd54bb7bdf0d16050f6b4b2f52ad2ec18e8237e5db27ce5eccb5690e3ebdf4b3046953e8f212a1b9c16c47011ce6bbba8cf2f368752d907f28aaa27f30a1e368de4943d3974815f38276490b04fa7e063ade053e5ad1",
//// 1454 -> 1412 -> 1400
//"8060000100000e100bebc265dd82f0d558eb19c82f2aed595fa177e77f972e0da0693b2672c19653aa0f99f9a4c10b717c4991208e634e3beba3f3a4e8c474659709e6aa73c9e63b63353139d69ddd23e2974f36c497423b13dc3e356007f4ad61038be602c9f47aa194c2ff30c50fd5522a16eb18643c982f2533f9e19b847e08ab4da204733a0d219d446f169863c2d8fec350a3ff6e511488624bdb4c0e86b366f854e7283ca56985b32281cfedb83ebdf82b85df99353c2e59572f282c1ad63c2b758c43c057291f25b87ee721ad64bb4b125b09b52643d1103847d2709dd0c524ac47f3a0a14cf1e50842bfbf965fad8cf7d06c6607f08ff8bcc4716d51694f7a9daa707291f7952cf0f07e22e15f2e5b0b17967a5a712802fb347feb7251deba0530899a7b18f6ff0448a06838e4685b4b4837b3a68eb61508983824d14c182d18a8e5cb5975b667a17e42ea6ae34664694c8c1df9d4820be855dc43b1c5c5a8fa6a3e5b5e0f81ad436847b51f7ab24e048a0c1a004fda07b5a4214258a04a3797432488769349919aa677ab66b9056162d1bb53de5ffcf848393cd39653bededc8fb2b87409d95b0325911ec22c889ee29aeb30a1fba547778b4e4804b261205134c0159b32daaf9e836281a0797991fbe3bdf061908db82c9fda8f21f7765f75db555859ffc5ef68e7961e8f976d6c7c116cdf329c15b7366f32cee1d6dd029987f3bfe02f4c1afff80700bc1261fb568deb774e270955952d97b888c2fe2b3a534342f407b9c129e3d02ccc7f8c9bd70de35f2e304ba725b1d5b64fbb34a6a50d33c039f1fc553d9c3dc7bee3e8c14b9e68f6633a3955fb28c2897ec88779d1e4be1e74ee19151be0857728d71586a2aba8e38d139289cff7608ff08e4d0ec93805ab414fb508c272fd27402bf787faa9c3b4c26c8aa1191d06c5488b32f6aaaa4557b5a88617399c6ea65e301572f1e807d73e6aabd30c72d5d6f5b930b4b78f3a0f20d9e2b678211bd5d0d8b8d0336a60658c7bf5ebe910bc0f35f936cab415241ad22f076c105d66615a84dee8b0d7564dae8f617e3be7ae6b53d61e74f7e0a8fd8a4d25893fea9e3f32e86ee496607985e6e0df33432170d87ba1289122764a98d7b807857504bda55233b763f879e58778fc34491e66a7e98e63f880f457794947dc412bbc13b0a58cdbc447175f64c18ba106e846e26ea2f0216cccfa3d8eee0919371d07e671948a4375034b960a1e2abdc7270da3fb1cbd4dab20357c6d1fd15f8693c4da1f60d5dbce0d82e82c6437e55d45786fe803f86ea6635a853e36010e64d8ce5021574bc6003dc793b3d697e39ef28807bfe9e58cd0f1627792b689aa0515ec455b97ae6e51c67452a80aa0c62a6401f5e196577fd5734b5611eda1dc2cc5b7afa3da64da2655a55a9bf69a05033bd7af4abaf308eecb56e488e7a023e330604a03a516baf34a2d75725b7b2d17e73793e95b67df003c04e46f72392500d251440599ddce947b51db6cbffe7282df219418ff92b67690410dbce4cb55bfab1d8a3818c49713ef39f803f789640fdbf078b43877ec9f9f5cc202ff846657d3355d0d9187876b87eaf2fe53f531bfcafe1d29752aeca6ac96c71a436a443e19ddcdb26b542791020f6948226156d3a818c5ef7a9ee70d811acb89899350d02e997528a428794881eb48a0eb978e6f43b20fea3b354eb953ba695e3902256c6eb80cbd797018485a28db5e5e4ca9e3a8853464d211d5f049c65a487114120d90178658edf00925e3a8650ebdbcba23b15eba561ec7af5c600ca3011cccc87d761d0113c7166d95e3a5fac5596d5d2dcec5ca573386714256cc762a857223327bd944cb2b37875636d94764d5f9333ca40174ff2ad248a85184e3fbb94654a5cc51e8adabc62a6d16f010f80b0de58f8f82ec2af775d7cc849237832b95e57e7a1c9eab0dc8de3eeb3069893b0bac291c41323082defd990cb4",
//// 1454 -> 1412 -> 1400
//"8060000200000e100bebc265618fa33fa65a5d2a5a8fd29ab490aaa0e9d54780791410e83ceac7250621ce2ba2946a4e5055c0812ae0427d1ed8b6d26214e592ab3b1402652e35c9fa4253cd81e5f7be5efc645a8503020455fe33c4ac5e6bfcd57f7b21e810e623dd917aadeb1b99534cd43f7463692d54268685d7e10c0e729fa2b562b60001884b0dee83acfddb9a28fa189d47744d94d023a6ea376220eb2cde3c8b12470c6a1f629e9ca204b2a79033185f0b1348a8008b162a78a5f4b87584a216ea28236568e50c80824b20e4cdc188355edc4e7bf08e0a34765baa95eb5825f786bb5eba8daa8d345ea81adea696101b6d1f2fcbf67994fd1fb8641a1bc377bd0e2f9d67739cb1c5a6b3f4396a70b2e1a499523eebbf2300a2c39b39bef8b80809b0c94e4e2272eeb09ec8b4ddd6c87a1f7319b95cdf44aec8a6cdca1ab2a0519db5fd65adc5aab4f2a0b18bf3f27aef2f31ae81c296180fc7a4213783b230d19a32a8f75aa9b49c8a1d7ee251a14b2e6deff13bc884ce41b911d8db0e915eae83e78ce1030290da90c7ba43e3165af99901e7f5888fd45f8b4b8775f3de35b5e56e4e0492120fa4b07d3ee44dcac7310167e66f7a0e36a2c85715239c8021fc9ee154cb1b9ad21f1b6885fc0283218102fcbd46227e7d1d56110e6bfce015b2679e66c473f6a02d4b1099e3330b0bb9cf894e913f938a61c8d6d8c2059bee9a5004bc152829683967e2ee8d112c260adaf80713bf3db51cf5d84ea9325b8fce1b6719434d783659d32ece8661ba7bff955c2f01505748a4d4384430520232baec06d8e9ea00851c97c9048b84f9109a29dec4b6ca756ad479916be1b990b63bc7918e1bf7301e54804e05e3a88f019a34f0793c3c0fb9f5ab217b505974fa522cce1952660d9f976b5b6d74e1a8ea73c56ed4356a63ab12998cfbc6440e98dc13b7d3da3edc9aaa05c6574dc8b49945b935cef864ff896c7049744fad7fdde283498f7ca1f70be72ecd77f6e502b273be61defe78fd353b944251fc145b14710046e70e667ade03e641973d014137d4553859b9d8b57c5d7c65c4e5ae65634a8ccabdc2bf07f079e1353f868df016970a6f389dad439b299588b27dc8c7fb85ff1219fa2e94422eaf929972bf6d70fc2e748f0f93f3cc4f7758db091335d6aae3b8efe8ec42bae5db5233a72b98e412ce920440baccf3f1d213139ed019e9169ff61886e3cf46563bac312c02ec58f141dfc21c231479475faa0b9c08b9b34eb8131b6371f6c808136dfb2485d60d4451fb19e5406007fca2d239a58ac93476a0a95762da59e61b4f6127383209743143f2c980d241eca572f3d4b16133d000f54598c51605042d1b4f7f3936f86a8306d5da0af25bac9e90e1f163cd4d0ab62da1c29415b3ff3baf91418da7eaac3d188bcd190a841ce29ccd611822c5beaa8f3dfac04fce5fb475154ea818a5fbe1726f3a98bc4bdd34692fb99133c8c0401976d44dee1e2bbf71eb54df8bb8ef689ab1eb6a74836db68ca5d7594ece13ba31c9117aff30defb8496005a837a8a9392d78ba9b0b908e3426ec74f9c5c7a39a2f7cea193af68679e9d4bb4de38cd378bd4388285c9a822cda83ef9e5d0d6ef533ea68bf711fde1974b6b54e009fd59adc541d8e13b2d797c947e53fdf7637058fd1428402fdd6998621f0d3ab6bfb634445e13d74104449aed136d7559343541788e70d79179a1e78b2162b290b6a4f8282decff8ac138407309a84eaca9f70c8edd1b5a8dacb3c88a874660b8a2ff2a4e311246d13d63775af1b73070e66a5f0af057ae14cd085aaf343fa8c3a565abe654df95b62069dd7730ec52e005ace0fc4bb99fe622b63af4a00c7b9f4411c6a4bf1b0068ddb55eb08e590590f68fd50ddfc239724a6a17dbc5642f711f7999c1a659cb2288832b571c191cab2d798c17e43739e030629e71bbbf6f28b0f354efaac7fcaefffddb0dea34d4d1a8b6",
//// [no93] 234 -> 192 -> 180
//"80e0000300000e100bebc265d61fc47fc683f14345290e9ee6b36c8c5ae4083f03f2d77ffe2a2e5c85d438977626c1543b527fdafde185058952dd2ac26987b236f47319998b45674b5e3b0bec061d23292ead101f9c3123cb0b64f515ad338756b7f696886bfdefe1e9b53d2fd50b287b8000869e4d3fbcc2c08ccc2d18d864b0d11dbb61ca0ddcb8270e83904b21203154a13d8b2fa06fb390dec2163638ad2e79f2d6841c80cf14c5bfe097ea48f8220eea4c5053b55e8f1fb30edcfaba96",
//// ----------
//"8060000400001c200bebc265000001ba57897ff16401028f63feffff02503cb1000001e017068c800725e25ffc59fff80000000161e0b3447f508177bdf98a8d6880fd1e00af1ee03b8cad20b6b42027978c4196fdb04fa9621b7d691c71c337beb349213efd5e11ac02c05ec3d1a5aed43b90de12794a82e75cf0dcdd2d285c55546e4c8c8600b2c11cabdb5b1f21a2f81fad64ef23cf92043a24ada22085970d2340865a5b75f363a8eb10e034a6b001aaea6d09c816552741c3b7b41636a855b1c8d6f9ee499f735a5a63ddf58f9229f38ef174c0d8f6b96e23235bea41a98807f8478edfeef98d49898f437ef4c27fc3b6f9e20457439833fafa2378679555194927ff1cf7445f6f93272905a6fdb48e4ceae8ea420404d5cb4b06da9cea89d847d1063320ce0ff6032156eba85ed9395474e3dcf89cf6c446314874634b0f271f7a7fca4afdad638cc5da73ab33bd54a8fa1677a65ed77ead856c4022d18c18a90b8bfeb97a8bc4a15dd031bad0987a51ca40077192e6d5a43680447370a080b44891d89435cc7a8fa6f01664439c3931e0a33b40d31a034a30c64f538e34a969bf4e625ef20c538adddc348a7decef7978de18302075e6cf54bed6a429c65d204efa05af5ef454de605c5592623f8d7e30615b34d969b2fc6730ed15fcb43c15c5362d7296f8f060d0fdaed28e5c6e0c0189b23c2f2b83d2f3e3908c140ce62793d8a0f06dd16f8bd1d15f3cb85c4ba999cf10ced9166314860a4c4042559805e658fe1bbc237191a8ef615b804fe887586fddfe12f8811bd70f157d0a131a3d62db870bff0f7907aa89f5dac454be895552385738ac52e1ff1b06fabe3456984b712dc1b62fa49ba148c478eb37b68fc496e50d3af3437cd641215e53f59a26ca95a77fa61454a850255021037bd3dd0248c8b3f8011d80885a7cc2c7c05e77e73bfd0005c9707e740c8afc87b4a273d3cbff104b0c131894c43d5f687abda33bb4f00c7a7db76940d8412a4f1259b385d58ac2cacd67e5f07e83dfd329aa408777d05d0a4dae7133a2e982daa4421a9f1ab0c2b2a6d42f1515ce4d872f5876c4bc42634ff0a23ecc8a7a702e68c071bcd6d388cc0fbb523135e3fe22b229c3cf01ede3e288ba247ffbbcdb3f37131354e166f15ea9d2e33e4284d3248c4decf1cd222087228be0c8d097c1e70ac686cb2765359a48f8555aa82d59000a44f8a8cf8130411acdca5a54456352d895ab361033a367ede10c5f647ce7f29b0a8a34869570a6e5019a1aef96c604fe2a6b7c2f333fca8547437152c0050758e93d3f55cea250babd9bf6f74c45082075de09c2de61da2cc289198094916dd6dba042b15ae6a0818dc2b11adf2a856700e8d7f5370942da73f65caf17eed2241865fe1a34b74b7afc33b2af1e48be7df5d56adc5749e4af7e4b3564b14f9a02cd6f2bed40bd395e0e4e4304f94f457a0b8336ff2d6f7c07f292ce1e1a409b93b2f434161e32cced2f669e1299fe2d5f681ea70ba1e7229a9d3ca8176557d7b3207fc6ca79ed9999b4c36befdd19fcddccc305bf30b03688a5866dd116173c489835c9fa9c92ba10bc41eefc4348736b996fbd6fa278aff5686126eba1ad45bab0a75fa90acdf2be78b44cd2f41bf08458a981576f12fd1d2a2e9ab34ffbd8b38cfa950ebd68192803d11a02dd118474895e40c967b085b5b62e300d029b90621946fc42fcb221823480c9eab0fd0ccc3868401179d21fee1d9804473d401b11a9ae715c09651f7cff9d4624ae8881ed76b64ba03f152d061ca236d876077edb313544ceff4721a30cb7c057ee1bffe926ad6edfebb37df8eca4a6e0b36f1027dd526ada738a18733dca245525954e79ade5ca3e51229964634e8ae86c30a55a013b7e4d9a613c21ef3e6e4ee5f8fc7b33d2cb867da3f284308977599ff24591dce15dc79497ff86b375c3676cd1a43fceb00df3290a83705a6bd097b0a9a8a1d2ae48",
//"8060000500001c200bebc265a97aa1a5e39375d81eaec1db4d4a012b57439bf4fc28195650364f3db964702d05caa04d3803d088eebd0cd7ee3c57ac5502b4a3d10813d22a76ad83f1c06282e7c5d5995c5034c2949fc08d859d6368683af07c1284c18f92e1c0c2a9dfeccbd894c7a449098b1d13ab09238d97a7d728cbba932ad4f72e238c4fc5ba3a15277439331f0fdf3a944cf95685a5e16a55da4bb4af36078999e7236578e44fc0a7dcd7ddaf85498652de19bd90505d638c78a3e076d26b941633398e7de1b05833c06988e1e6859d42cf2a9418bf56ad5b32d5b08a6a9ba05dc50e08d9193d1b1de1734c46cc89c2c02d2beed1f2c8d829204bbaa61632b9583dad8f9da1e4adef1b81749c00233fe5a3927679955be8ae46a3f8469a3519b5dc720b786735c291f6dd3915533e24ec428d3799b137c3c642a4e1db0bea0c69550918cb7dcab850b9acdce6fba9787a1adf86cf78b308135e68e2578655d9933f191eef12ba44acac526e662153994d68033ca03e77cc42c8d594b81d960e350663682b7fb60ba013cba71b698ce635bf90be3eff623fb3742a2ecf3409d12347d9e0213f7622036839387b530deec491a1e55a3c89e2a627d61ebd662763eb9360ce91478df77ef8ad795b3b4c4848cf16587df5a70eae6ec73ab3fbb487541d277969f9e5e1df43ce813408657d1f1e44f722e5b6493c0e58aa5133d2ab2213654489f3274889365742017460b1b670497e3ee8f37df33fbde70054d47461da0b67344fb1074063251607dea8f564fafe195cbad67b2f34d260d59b17fda6af310afb9c112d2a63b517f3a3017527e8167c5256eb374a8fcd7395ba29ad8cc949fc1598be2b41df21eb10a6373d5149854b472578ff275c23de54ebf0dec31783b1371bcc293642fe6ed56e2a06ef86210fb974f3d5814df03c2861a34893dbb6e8ed2761e3357707941e8ee1ec947e9de3d6a7c71048d0a1397a58cf1e82b4b031dcc401b25dd91fd83f05967a504a2bb696b40d434a19e760c2874eea26e16aa5de48992f8ed8313956d342841704f3a8804e4383543cd8be563a4d5309bbd5de7368194a5d5fea5fe9a438a94591848f8f8c146dd7fb632b96562099162fa0c8d005b737e285b41b08cdfa8b713d68920c4466961ebfe8801dd77acdbf3db5b68b00f63869bd94abd569853c6e5fcd6a714af79a5113fbc03c137f13c9392196f054496f975182939f07745043be2bd37119abaa87b335db330e205b4a13bd4e810cf1ccae1ef67a507e6401f600aba524acab4866c237f75de0a7c61eabf8c33ec25e7ad7faf1ec1993a82ccbcbe458af21c2cd485feb57f42aef738d7671234b8e14e12d347431f678d57ff05d818eeef3f997f10538f7380c5766375c43f355b5ab937dd2b64ffbaa46ea142480bce9d483656cef52b54c4c1a6344bb4b3eea1fb8d1981826924e6f2e4ffbdfaf90cf10faab955ab2318e31eb45ccef598c479c0e1ad90f0916122fbdc72d8334194facf0d045d2ac436d3e19fbe1ea543403811cf967b9661ce0c581f341fd559b404720b031b82c2642cffb4f3da3a10400e4f2c624191784fbb75f83131ec641b3ca06e3d1ab6dbef9a46acbd0811e8981bf9dba0aa305584e1c25895f9d376e3674c087c84d07229fd5923f86217a38c274ff31c49ee356e243904ff6c36f350ce5ec6269b94acfc41576aeede7e901e6c33ae5434e1bfdcb2b3dd1a255fe75869ec3f393e91963d735a3c231bb011008514e9ad090941bf6a6b3d10f54533275f01f4080ae38c2be67252ad96c3f0b315da35ff19c723988630e5fd6a20a60a5ff1ae4bd7666904ac42646ec3fbbbd75563e5abcfb13249bd14a7d6eb6e60e62933e0da236cd6df8aea0ff16af47a5dfc059b79790e8d82081e3b4902b1a40faeb3ee99942fd467df683ee940217dba534dc0500768fc2fbe45e2d7162133a57912dac9425de8edffee3ed99",
//"8060000600001c200bebc265d46b2a855f0979f947b776488aa420832509984e76a4263f1da61cacb5d0e4e7497bfec631a84a2431f793f699619af6359321d3e0264cb069df395153ae9fcabb67e19b62b05a1547245746c04c89f719023227622b88456a639d8cc7ec181373d21d4443c1acab8596e7c06d6c9c7ee9b0aa7aceb65418310ecfe1cb1a555f69fcc822438e97834f1f98b953e889cee594327a41ba6352c8fe9cf0498ea3de8e6a62a44be511a3d30a3ebb1a4024286f1a37d0f08cd2fb6c6d00911d1c0631c6608500777e2017ff83a9e45b99aa8bc473412ea04e0e266f34c665c9d9c3768e711b015ac81e49034a4b35dc83e28ac260d14807d71ae335cb3df3e9a9f591e7e612de7228d735c0d939043e085ed5e00b1357544f83773e012ced88ed10ccaef40a8d82fc0119e595926c426743f7301679b1aac6d8ed9f9ca8583905436d8bda516a374cb06ba9ae2b70eb6ed9e7fc656cbe6cd75e62e8e8257518e9a9a75356113ad8b720d5597def64b68200ff5358ff6570fafbff98d74a4865c7d1d0419759e97e6ca5a538cf8340f19ff645bae503e891d5cc9f2961422f5769df9edff24feb5758d694d1e41062bfc06fc59ee7e686f00c5ef7fb5cdb09f1d57770bd817c718a0dbd7c5c1472e47d792aff5a4ce1e3990e281550b4b74fa5cd45aea6c5bb9628042a0938d2e0aae79f1166027acc6259504e3d77c9009d9d94173e4459ffdea52eecb21d8a6549de66cab1b459918d1574a9556c45a580804c4fe1a6948c9b0674f67954cbe3ff99084c3978b736e364955fa9dbb7450eefbe41bd48c7f1575557e5533036a4c430f4bf223bb3482c85f41bb2873fa708efbda8f4dee1bbe26fa3dee123bee7efa3a8152dd7e665bf090e3a4ad1ae38347b17f3c268a20ec7bf004275d02fdc5eae135d1a539ecda0093e38adee8c225db73790b4b9bb1cb925f654711699da495616b16ee5b536fbed39ee5edd179a05f19d6c05b91cb16b44ffbee7031faf2522128a47b7a5cf90929781ded460d14cce7a9422885e3634dc0120d3d397c72bbfaf16c602363e091879adf50f13d5b32b55335608b280e5df3a26178ef64f7a54ba98328a870a399a01debc8ce1147888beeafb56dcf746e12f15b7b330a71d6afbaa76fb59c55d6dff2cf2a28e90b63951f15bd578d15f2999fff3fa6b89d5702e26084b4054b186bb6dda8063cf173f91695dc9ed6dd129408f784f9f971b1a376d6a44985c25eafed83fd8d306bebc4e605968996aaca8886ab7ef3a8af2ebaf7c49bed092a0abbb9a1a8bf70b2954e7da5dc18ae81528c258d0ac02828b544eee8623fc0a5de28f8bf4b11bbec083a5aba39a4641f344059a2c354b8ffc7a929fc9db43dd276c5c86eb3d419347daa0ccb59dd9ddc0d489dd807634d9c44174eab051b85238ea59f2b53725a0415c606f8cc6c1223d8167dc32ba52e910b5a4dfeb6f90dd4f8eaf15023672876e54d1e591805a8ff3370e5505196eb80e9d1ee3bf0af8584d1c80177d48f3a93688cc725b598b3a6f5da6d5f9cc76312f352a0277d2f1a280b8953467e099ae2589875d3704d31ab03f7ac09e12a85f49c2b3c36e3ffe978750b3168242034942ac2e690cecbccce9470f737e007eadbdb4eabe57a34723e262690da3221f2995f66eb4fbfbdb9e8afdfc0fccd40090719195e07fe69f96d7a9590f9b4cbce1ba723ed94b71d94c0c681ec6cdab8a9a6bf4526131bc30a4ba45db01a617fdcf36bf65a605ee33330c8d5adc7d744847a64d36ce1cd97898ef1c3546368164b2b649b155ab082ed1a8055027eb6e9e9e00dcd512474ca1b5ee3f663e2b1385854f60aea222e7c9d0784bc7771c1f827e3acff63cefec2783c1bfc0f7ebbfa5a69cd3e6c31bcddb370511cf8fa06496fd53273694be86e8f154db8debe6382bd0bb681b44d8937889cc6bd63b7a51f3e08dbe00e87b05b527fbcd44a18a",
//"8060000700001c200bebc265080a5c960303513f171a5eb48da8d0508bb9b95672daca349f439502375895fdf5ec48b8b4628fb8ae5053e92ba5569a0d6f629e61862049e627d01197ecb8d610dc01e99d7eb99ff518a482d8470ca587d64fa7a320fe3e466a58c1b26ba2c61bb57a81bbc96a66697b27e74ac1e94c06c862768d081100e38f2406854ea21a90587cd766a4ff7a743a52e9bcab589eff6afa4d72e8be357b5d3ae6d954afc95720a55121e0251f01d8eeff72eed42b8793f02402c9ad94993b519ee28dbc14e7d6b784f1c52435a5f9b10b39a52a3cf60399a3ac5658eebe9711000c5fffc1006189e71f7fa6f271489546bb1d175f8fb1366302bdae787daddf22af3d50c9bcdb6a1ae951ca55bcae4f28a02cdff09f7ecf31a10c6ae6af67a473ce89de6da5fb852810acc7ff1a6cdc38930b2040f4226935c2efc66fe35389beab17c8e847e884cd42cbc37205a71eb72475b3403f06553d78d388d209960fb7a9563f74a36241dccbc5654c0dda3f95d90c285786d69199125662e38569b695771b801514fcc2f36277ecfcb9b3dacc2ea50f1d69cba381fc48aa0d075c0a47ffb9253940afa66f45c5471f78374d8c171fd70f96f48fe865b34dd9b33e90af928fd2b8f15e9be944ccd9fcc06293ad918f2b2ded8af30d4186d73aa2b20de22b5a6ee5be97ef79427ad5e65fb91d8ce0cf7f6a9e1a32fad978d7a79e29f0403ae8f05cacc6b46c9e30e4943df1ae20de5f985497245fcafac6354057a266a7f6eb8d6b5a115e351d21352884f4415a88194551931b6db2d153e47d06d480f31650aef1d1c68445a619f0c957dec0762735c37b614fb7561947366fa47afa64c972a4501bb59e82a098785e87f564992bbb2c4d76892a848a1125059dd86b8997297cf95b6fa11daf03377907a52e571e2a193efbf991168f776056b569d8bbb823af5193ee0295d23447f3ae011389a90194311d59ebf536d36d40ca3d82ba639df5066ba4208efc9166b52248553210195a9bc052a8ab5bba6043255d92451049e5a7cc0e69b99e305785f236a64202fa506863867d8e734b4de1408166219e66d6afc22ec1bf2332afca56c6341f704025bece5c15964797c8561952f3dfa0d4de4d183ec4bf6ce40be15a0b27217eb9e9656212156f3fcbc43179fe0663136912ad3bba75829f74a1d63f2dc5e3256fc22a9c8186cdeafe6f3f2602dae171c5099e72a7ea63352305159fb5b85d735d460ba20b4447026be7a70001301306a25a41af36a39aeb3fe22c598aa8cc56f66afec3b8067516f7b93754c67d919ea828da0c43df85f3268e95d09373488706fdd36357353fe2cf7268f5fa851688fff1921794b94037dd57c152cd0743bccdcec19f4155924e5b7c16e2ca6bd8ad9d23e204ccba2183aa3b58e357fc8e20c7c33ca73f307df01d9e1b59bc21f92319d494b4d28dc4c44e5f19f1a125eadd67ca2bd247defcef7793e1a8c87537a3e4d39311cfa9c0338204b3e1d568f00eaa9bb228ffc602949af9115706a31eb72bdaf8d0ab558cfea428f763b7e9867bcbe80231b2bba5bf35820b0bcf5674c5f06e5a69f03ca5215011a172e62f88d7151b788cc6f18e40d58e541503214db4f113c88ad7e746a4a044e676fc4a2fa87c0e5ee7098ff7fa5be64ef0f336dee08135d62e9bebbfb7895ecdce57c39a0f5aaa9002c44fe4a71ddc47219db5f97e858de8bea514040bb633d9bb5cfb5ed3148c7f9be70dc483965806b083f883df57e6693fe6a6c5cfee31c1e886e56c1a1eef2533fb657e1c52117e43370cbd8b05b5d9c070a9cc4536178763f508d18e4994569b29416ccbe096baf57d073fa581023b7b6af1a337d36d991d4c61cfd08ad6ca5a55edbd97ffffffffe5ffb689256b9c90a8cff48271d1f59ac48b127107c4e786d476862bd3e8dcbe6020761269a121e940c594417804eef44cf7a70302c9d6a421c7ffffeb4fef",
//// [no98] 374
//"80e0000800001c200bebc265b1fa7068dc4693dd166d9097f5ed5df5a7e7965974f8f64682d3dc0f9b42a8ed2b397f4e9dcbeb6ed3636e1386e1ad3e51744a9628b9519d4636b37855feeeb9fe8fe114ce60817b6bd67cf02a9b80e375ade80fda060d6a94879890440f9f89d31761109a96641192ecadcecd6a52a01f5eac0516e6b60c6987e05f6f79b35ff31d0fab7ca9d0fb9f33da79974e53821f773cf61b12bc3ce5c312f61a7c74f5d7f68394523889e6e8eacb27a160a9897118c6396d7e6720ca8a3f35337e605cf6007d3284894f1a80ee82085b0e390d18278eb46d370b6e902a2e92f24d431d474d6e2eb029f8750053cd012b0c13f46d5e5b9dd863abc3cc935591cd773544b16f3e6b4804d5a3c4efbd132f9afa4ec9d502c9ef012e7f9ab734d1f6c9b91f1e9a1d5383abde0114bd8805acb93f51478c7ce7ac30a8ccd53ad38cd3ecfa80",
// ----------
// [no517] 1454
"8060012300032fa00bebc265000001ba5789b48d6401028f63feffff02503ce9000001bb00128147b104e17fe0e080c0c008bde080bfe080000001bc005ee0ff0024400e484b0100163ec6b4b4c800ffffff4112484b0000000000000000000000000000000000301be0001c420e00006000078004400100ff001c20440a0000800000000000ffff91c0000c430a0000fe000003000003ff3e53909c000001e0002a8c800925e26d2359fffffffc00000001674d002a9db81e0089f966e02020280000030008000003019420000001e0000e8c0003fffffc0000000168ee3c80000001e0f9ee8c0005fffffffffd0000000165b80000075573fff2774c502eae9ec9823c7527a0ca8e89782fca9fec3b08e7495a4b28c2e9af51cc5bdf762afe181cccc101cf41d775c319820285d2d3bb42b74a490a61b27efad77c59e601e9b8bfc1059e0c89308adfa8440838abf6850af3abb13c7d4af7cb4245340775780f7c9f6f541e588bdecd9928fdb8ebd655be907f76c7d4bef5840e6ab9e8032ea6e66a6a176d63aaf64d1d12c2ff5ed0ce0fd41cbdc387fdb58dd7521e41b204469568ccb9f6ad75532e0cd898133885f5ecaeacfae4b94069c816d8e63595172196a987219a13c37aca9b458806fc805bf30233c82238e9e9e93bed9bbd8dd9d1d42cc3b77088ac3fc86c2fa4143884e5b42e1846f9c8eea24738f7c8ca9c98309aa8e7838a5a550a84efb80a13feff3a94872f0bd4cbd4f1cc429426775651d1f0573e6c17f1bc7867cdfa1500bb84250cbe821fc376db5a0646afd359c997393a7cab43b7990f8869e9603b2557c8d7a8ed2424a1de7525272f3fb8731a751e1c4b2f95ca03c1ec515b5ccd7e1d659a182c6d101be35483eb085a520be35a1ba2c5536b265bfe7cf574307214566c14ce86d0b1149fde75b0dab165eb4aa012f820271380a439f0142e7c859e299db111478d18c2bb719b79ccd7d89d79cbe060aac816c5b82802836c48b7546a2859a4bdd90021cbf74792d8b449e94a8059dbe58a52807d2f3231083e6ba81b587d61209fdd1b9828fec3db125e684766ddc7ca7b3a4afcb162b4c10eebc690ac159ab6e8aed6a4c9f47ebb4db54088773da6deb07326ac635fa6aa6936efcef6711903a5d4b11f87e2c03601d48e678e10ed0bab18948231742c4a53c0ab8b567f3c10454f9983a40401b6049277d8e282097718ec31a17659b9c7f2c32bfc77d2b8c343ced8d8527fda1391863b96842e83d71fd15db870551d8612eb7d26418cac5be9080295a94010655d21c86bfcac04c19f974eb1f58959927ff985153b3ca364d3ef61d6d98710b9cc18555b47c4750b634c1faf980f03bb278ac424a20e950fbf7bde758266bba61cf3d8195099cd2385e92b823c1a7ea77d5b1e9bfaf98027b39d3b597674b98fde73c2f36e13cf39d0312930f502397d3e52e3b843b67c7f8a9623a78784f85dfb4a6714c614c056a3f99afbe61927fbe8e4f4fe1333df9f39c506866467386061a948ee4dbad66bcd6b0f778cb5ff245ad731093ddc6f965d647784f0b41db69f2d47ad9c355fbedf8ab69e053a0d4159553da3e337b56cf4fb6fe39aa3f22d60ce0146a17f62a6ae31a0402c455adc1b5fd26958ad2ce470ab23d8bc827a8bc208e0aff42613d5d13a6315639a907180d53125e694df885948251e477d856fd62b9be679d6a15e7230c99bcd2228ea93d060f63a5daad671a85db12852e4ffe425e11701d596cf830a646901ad64df794c5994a150985767b2da1cf5fbd1131750991ceaa779ce74e8181b5524b88b18b4f3ea5cd7446f2dad270112ff511a571f4b8efb8839e35c08ca2637aa75087ac9592fa41f5f5b90fab4962c7b4a1c8bbaf7b34d921b689d713a8dcba76815a330e841fc4446b16b6cc4c7a8c168806c1eb82e56850c917d6f1920907a61162414dc3d23c154fe2fce2c3dd41a606b61522b1dce9317e5a6",
// ----------
}
func TestPsUnpacker(t *testing.T) {
unpacker := gb28181.NewPsUnpacker().WithCallbackFunc(nil, func(payload []byte, dts int64, pts int64) {
})
for i, item := range goldenRtpList {
nazalog.Debugf("%d", i)
b, _ := hex.DecodeString(item)
nazalog.Debugf("%s", hex.Dump(nazabytes.Prefix(b, 128)))
unpacker.FeedRtpPacket(b)
}
}
func TestPsUnpacker2(t *testing.T) {
// 解析别人提供的一些测试数据,开发阶段用
//test1()
//test2()
}
func test1() {
// 读取raw文件(包连在一起不包含rtp header)存取h264文件
b, err := ioutil.ReadFile("/tmp/udp.raw")
nazalog.Assert(nil, err)
fp, err := os.Create("/tmp/udp.h264")
nazalog.Assert(nil, err)
defer fp.Close()
waitingSps := true
unpacker := gb28181.NewPsUnpacker().WithCallbackFunc(nil, func(payload []byte, dts int64, pts int64) {
nazalog.Debugf("onVideo. length=%d", len(payload))
if waitingSps {
if avc.ParseNaluType(payload[4]) == avc.NaluTypeSps {
waitingSps = false
} else {
return
}
}
_, _ = fp.Write(payload)
})
unpacker.FeedRtpBody(b)
}
func test2() {
// 一个udp包一个文件按行分隔hex stream格式如下
// 8060 0000 0000 0000 0beb c567 0000 01ba
// 46ab 1ea9 4401 0139 9ffe ffff 0094 ab0d
fp, err := os.Create("/tmp/udp2.h264")
nazalog.Assert(nil, err)
defer fp.Close()
unpacker := gb28181.NewPsUnpacker().WithCallbackFunc(nil, func(payload []byte, dts int64, pts int64) {
nazalog.Debugf("onVideo. length=%d", len(payload))
_, _ = fp.Write(payload)
})
for i := 1; ; i++ {
filename := fmt.Sprintf("/tmp/rtp-ps-video/%d.ps", i)
b, err := ioutil.ReadFile(filename)
if err != nil {
return
}
// to be continued.
// 这样解析是错误的如果内部二进制有0a就过滤掉了应该转成string再做\n去除操作
b = bytes.Join(bytes.Split(b, []byte{'\n'}), nil)
b = bytes.Join(bytes.Split(b, []byte{' '}), nil)
nazalog.Debugf("%s", hex.Dump(b))
unpacker.FeedRtpPacket(b)
}
}

@ -12,7 +12,9 @@ import (
"github.com/q191201771/naza/pkg/nazabits"
)
// Pmt ----------------------------------------
// Pmt
//
// ----------------------------------------
// Program Map Table
// <iso13818-1.pdf> <2.4.4.8> <page 64/174>
// table_id [8b] *
@ -39,6 +41,7 @@ import (
// --------------
// CRC32 [32b] ****
// ----------------------------------------
//
type Pmt struct {
tid uint8
ssi uint8
@ -66,7 +69,7 @@ func ParsePmt(b []byte) (pmt Pmt) {
pmt.ssi, _ = br.ReadBits8(1)
_, _ = br.ReadBits8(3)
pmt.sl, _ = br.ReadBits16(12)
len := pmt.sl - 13
length := pmt.sl - 13
pmt.pn, _ = br.ReadBits16(16)
_, _ = br.ReadBits8(2)
pmt.vn, _ = br.ReadBits8(5)
@ -82,7 +85,7 @@ func ParsePmt(b []byte) (pmt Pmt) {
_, _ = br.ReadBytes(uint(pmt.pil))
}
for i := uint16(0); i < len; i += 5 {
for i := uint16(0); i < length; i += 5 {
var ppe PmtProgramElement
ppe.StreamType, _ = br.ReadBits8(8)
_, _ = br.ReadBits8(3)

@ -10,6 +10,7 @@ package sdp
import (
"encoding/hex"
"github.com/q191201771/lal/pkg/avc"
"strings"
"testing"
@ -576,3 +577,23 @@ a=control:rtsp://127.0.0.1:8066/demo/trackID=0
assert.Equal(t, nil, err)
_ = ctx
}
func TestCase14(t *testing.T) {
golden := `a=tool:lal 0.27.1
m=video 0 RTP/AVP 96
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1; sprop-parameter-sets=Z2QAH6zZQFAEX5P/AycDJmoCAgKAAAADAIAAABkHjBjL,aOk5csA=; profile-level-id=640016
a=control:streamid=0
m=audio 0 RTP/AVP 97
b=AS:128
a=rtpmap:97 MPEG4-GENERIC/44100/2
a=fmtp:97 profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3; config=1210
a=control:streamid=1
`
golden = strings.ReplaceAll(golden, "\n", "\r\n")
ctx, err := ParseSdp2LogicContext([]byte(golden))
var avcCtx avc.Context
avc.ParseSps(ctx.Sps, &avcCtx)
assert.Equal(t, nil, err)
_ = ctx
}

Loading…
Cancel
Save