[feat]gb ps音频部分先加人缓存后再根据时间戳来回调

pull/166/head
joestarzxh
parent 8b3958fe28
commit 01abed7b34

@ -77,6 +77,7 @@ type PsUnpacker struct {
preAudioDts uint64
videoBuf []byte
audioBuf []byte
onAudio onAudioFn
onVideo onVideoFn
@ -137,6 +138,7 @@ func (p *PsUnpacker) FeedRtpBody(rtpBody []byte, rtpTimestamp uint32) {
// Table 2-35 - Program Stream map
//
// TODO(chef): [fix] 有些没做有效长度判断
firstVideoPack := false
for p.buf.Len() != 0 {
rb := p.buf.Bytes()
i := 0
@ -155,6 +157,7 @@ func (p *PsUnpacker) FeedRtpBody(rtpBody []byte, rtpTimestamp uint32) {
l := int(rb[i] & 0x7)
i += 1 + l
p.buf.Skip(i)
firstVideoPack = true
case psPackStartCodeSystemHeader:
nazalog.Debugf("-----system header-----")
// skip
@ -250,18 +253,24 @@ func (p *PsUnpacker) FeedRtpBody(rtpBody []byte, rtpTimestamp uint32) {
if dts == 0 {
dts = pts
}
p.preAudioPts = pts
p.preAudioDts = dts
if p.videoStreamType == StreamTypeAAC {
if p.audioStreamType == StreamTypeAAC {
nazalog.Debugf("audio code=%d, length=%d, ptsDtsFlag=%d, phdl=%d, pts=%d, dts=%d,type=%d", code, length, ptsDtsFlag, phdl, pts, dts, p.audioStreamType)
if p.onAudio != nil {
p.onAudio(rb[i:i+length-3-phdl], int64(dts), int64(pts))
if p.preAudioPts != 0 {
if p.preAudioPts != pts {
if p.onAudio != nil {
p.onAudio(p.audioBuf, int64(p.preAudioDts), int64(p.preAudioPts))
}
p.audioBuf = nil
}
}
p.audioBuf = append(p.audioBuf, rb[i:i+length-3-phdl]...)
}
p.preAudioPts = pts
p.preAudioDts = dts
} else {
if pts == 0 {
if p.videoBuf == nil {
if firstVideoPack {
pts = uint64(rtpTimestamp)
} else {
pts = p.preVideoPts
@ -358,7 +367,7 @@ func (p *PsUnpacker) findNextNaluStartPos(buf []byte, index int) (startPos int,
if p.videoStreamType == StreamTypeH265 {
nalType := (buf[i+pos] >> 1) & 0x3f
if bufLen > i+pos+2 {
if hevcNalu(nalType, buf[i+pos:]) {
if isHevcNalu(nalType, buf[i+pos:]) {
startPos = i + pos - leading - 1
return
}
@ -366,7 +375,7 @@ func (p *PsUnpacker) findNextNaluStartPos(buf []byte, index int) (startPos int,
} else {
nalType := buf[i+pos] & 0x1f
if bufLen > i+pos+1 {
if avcNalu(nalType, buf[i+pos:]) {
if isAvcNalu(nalType, buf[i+pos:]) {
startPos = i + pos - leading - 1
return
}
@ -401,7 +410,7 @@ func (p *PsUnpacker) findNaluStartPos(buf []byte) (pos int, leading int) {
return
}
func avcNalu(nalType byte, nalu []byte) bool {
func isAvcNalu(nalType byte, nalu []byte) bool {
switch nalType {
case avc.NaluTypeSlice:
fallthrough
@ -428,8 +437,8 @@ func avcNalu(nalType byte, nalu []byte) bool {
}
return false
}
func hevcNalu(nalType byte, nalu []byte) bool {
nuhLayerId := ((nalType & 0x01) << 5) | ((nalu[1] >> 3) & 0x1F)
func isHevcNalu(nalType byte, nalu []byte) bool {
nuhLayerId := (nalType & 0x01 << 5) | (nalu[1] >> 3 & 0x1F)
if nalType == hevc.NaluTypeVps ||
nalType == hevc.NaluTypeSps ||
nalType == hevc.NaluTypePps ||

@ -6,19 +6,19 @@
//
// Author: Chef (191201771@qq.com)
package gb28181_test
package gb28181
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"
"github.com/q191201771/lal/pkg/avc"
"github.com/q191201771/naza/pkg/nazabytes"
"github.com/q191201771/naza/pkg/nazalog"
)
var goldenRtpList = []string{
@ -66,7 +66,7 @@ var goldenRtpList = []string{
}
func TestPsUnpacker(t *testing.T) {
unpacker := gb28181.NewPsUnpacker().WithCallbackFunc(nil, func(payload []byte, dts int64, pts int64) {
unpacker := NewPsUnpacker().WithCallbackFunc(nil, func(payload []byte, dts int64, pts int64) {
})
@ -74,7 +74,54 @@ func TestPsUnpacker(t *testing.T) {
nazalog.Debugf("%d", i)
b, _ := hex.DecodeString(item)
nazalog.Debugf("%s", hex.Dump(nazabytes.Prefix(b, 128)))
unpacker.FeedRtpPacket(b)
unpacker.FeedRtpPacket(b, 0)
}
}
var avcNalu = []byte{
0x00, 0x00, 0x00,
0x01, 0x64, 0x00, 0x20, 0xFF,
0xE1, 0x00, 0x19,
0x67, 0x64, 0x00, 0x20, 0xAC, 0xD9, 0x40, 0xC0, 0x29, 0xB0, 0x11, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x32, 0x0F, 0x18, 0x31, 0x96,
0x01, 0x00, 0x05,
0x68, 0xEB, 0xEC, 0xB2, 0x2C,
0x00, 0x00, 0x00, 0x00,
0x01, 0x09, 0x00,
0x00, 0x00, 0x00, 0x00,
0x01, 0x65, 0x01,
0x00, 0x00,
0x01, 0x41, 0x03,
}
var hevcNalu = []byte{
0x00, 0x00, 0x00, 0x01, 0x40, 0x01,
0x0c, 0x01, 0xff, 0xff,
0x01,
0x60, 0x00, 0x00, 0x03, 0x00,
0x90, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00,
0x3f,
0xba, 0x02, 0x40,
0x00, 0x00, 0x00, 0x01, 0x42, 0x01,
0x01,
0x01,
0x60, 0x00, 0x00, 0x03, 0x00,
0x90, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00,
0x3f,
0xa0, 0x05, 0x02, 0x01, 0x71, 0xf2, 0xe5, 0xba, 0x4a, 0x4c, 0x2f, 0x01, 0x01, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x0f, 0x08,
0x00, 0x00, 0x00, 0x01, 0x44, 0x01, 0xc0, 0x73, 0xc1, 0x89,
0x00, 0x00, 0x01, 0x26, 0x01, 0x83,
}
func TestFindNaluStartPos(t *testing.T) {
unpacker := NewPsUnpacker().WithCallbackFunc(nil, func(payload []byte, dts int64, pts int64) {
})
findPos := 0
startPos, leading := unpacker.findNaluStartPos(avcNalu)
nazalog.Debugf("find pos=%d,start pos=%d,leading=%d", findPos+startPos, startPos, leading)
for startPos > 0 {
findPos += startPos
startPos, leading = unpacker.findNaluStartPos(avcNalu[findPos:])
nazalog.Debugf("find pos=%d,start pos=%d,leading=%d", findPos+startPos, startPos, leading)
}
}
@ -96,7 +143,7 @@ func test1() {
defer fp.Close()
waitingSps := true
unpacker := gb28181.NewPsUnpacker().WithCallbackFunc(nil, func(payload []byte, dts int64, pts int64) {
unpacker := 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 {
@ -107,7 +154,7 @@ func test1() {
}
_, _ = fp.Write(payload)
})
unpacker.FeedRtpBody(b)
unpacker.FeedRtpBody(b, 0)
}
func test2() {
@ -119,7 +166,7 @@ func test2() {
nazalog.Assert(nil, err)
defer fp.Close()
unpacker := gb28181.NewPsUnpacker().WithCallbackFunc(nil, func(payload []byte, dts int64, pts int64) {
unpacker := NewPsUnpacker().WithCallbackFunc(nil, func(payload []byte, dts int64, pts int64) {
nazalog.Debugf("onVideo. length=%d", len(payload))
_, _ = fp.Write(payload)
})
@ -136,6 +183,6 @@ func test2() {
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)
unpacker.FeedRtpPacket(b, 0)
}
}

Loading…
Cancel
Save