rtsp support g711a

pull/251/head
ZSC714725 2 years ago
parent 6dff63cbfd
commit ffae8a4297

@ -11,6 +11,7 @@ package base
import ( import (
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"github.com/q191201771/naza/pkg/nazabytes" "github.com/q191201771/naza/pkg/nazabytes"
) )
@ -20,9 +21,10 @@ type AvPacketPt int
const ( const (
AvPacketPtUnknown AvPacketPt = -1 AvPacketPtUnknown AvPacketPt = -1
AvPacketPtG711A AvPacketPt = 8 // g711a
AvPacketPtAvc AvPacketPt = 96 // h264 AvPacketPtAvc AvPacketPt = 96 // h264
AvPacketPtHevc AvPacketPt = 98 // h265 AvPacketPtHevc AvPacketPt = 98 // h265
AvPacketPtAac AvPacketPt = 97 AvPacketPtAac AvPacketPt = 97 // aac
) )
func (a AvPacketPt) ReadableString() string { func (a AvPacketPt) ReadableString() string {

@ -21,6 +21,7 @@ var (
_ IRtpUnpackContainer = &RtpUnpackContainer{} _ IRtpUnpackContainer = &RtpUnpackContainer{}
_ IRtpUnpackerProtocol = &RtpUnpackerAac{} _ IRtpUnpackerProtocol = &RtpUnpackerAac{}
_ IRtpUnpackerProtocol = &RtpUnpackerAvcHevc{} _ IRtpUnpackerProtocol = &RtpUnpackerAvcHevc{}
_ IRtpUnpackerProtocol = &RtpUnpackerRaw{}
) )
type IRtpUnpacker interface { type IRtpUnpacker interface {
@ -75,6 +76,8 @@ func DefaultRtpUnpackerFactory(payloadType base.AvPacketPt, clockRate int, maxSi
switch payloadType { switch payloadType {
case base.AvPacketPtAac: case base.AvPacketPtAac:
protocol = NewRtpUnpackerAac(payloadType, clockRate, onAvPacket) protocol = NewRtpUnpackerAac(payloadType, clockRate, onAvPacket)
case base.AvPacketPtG711A:
protocol = NewRtpUnpackerRaw(payloadType, clockRate, onAvPacket)
case base.AvPacketPtAvc: case base.AvPacketPtAvc:
fallthrough fallthrough
case base.AvPacketPtHevc: case base.AvPacketPtHevc:

@ -0,0 +1,40 @@
package rtprtcp
import "github.com/q191201771/lal/pkg/base"
type RtpUnpackerRaw struct {
payloadType base.AvPacketPt
clockRate int
onAvPacket OnAvPacket
}
func NewRtpUnpackerRaw(payloadType base.AvPacketPt, clockRate int, onAvPacket OnAvPacket) *RtpUnpackerRaw {
return &RtpUnpackerRaw{
payloadType: payloadType,
clockRate: clockRate,
onAvPacket: onAvPacket,
}
}
func (unpacker *RtpUnpackerRaw) CalcPositionIfNeeded(pkt *RtpPacket) {
// noop
}
func (unpacker *RtpUnpackerRaw) TryUnpackOne(list *RtpPacketList) (unpackedFlag bool, unpackedSeq uint16) {
p := list.Head.Next // first
if p == nil {
return false, 0
}
// 暂时认为一个rtp为一帧数据(G711A/G711U)
b := p.Packet.Body()
var outPkt base.AvPacket
outPkt.PayloadType = unpacker.payloadType
outPkt.Timestamp = int64(p.Packet.Header.Timestamp / uint32(unpacker.clockRate/1000))
outPkt.Payload = b
unpacker.onAvPacket(outPkt)
list.Head.Next = p.Next
list.Size--
return true, p.Packet.Header.Seq
}

@ -64,6 +64,8 @@ func (a *AvPacketQueue) Feed(pkt base.AvPacket) {
pkt.Timestamp -= a.videoBaseTs pkt.Timestamp -= a.videoBaseTs
_ = a.videoQueue.PushBack(pkt) _ = a.videoQueue.PushBack(pkt)
case base.AvPacketPtG711A:
fallthrough
case base.AvPacketPtAac: case base.AvPacketPtAac:
if pkt.Timestamp < a.audioBaseTs { if pkt.Timestamp < a.audioBaseTs {
Log.Warnf("audio ts rotate. pktTS=%d, audioBaseTs=%d, videoBaseTs=%d, audioQueue=%d, videoQueue=%d", Log.Warnf("audio ts rotate. pktTS=%d, audioBaseTs=%d, videoBaseTs=%d, audioQueue=%d, videoQueue=%d",

@ -52,7 +52,16 @@ func (lc *LogicContext) IsPayloadTypeOrigin(t int) bool {
} }
func (lc *LogicContext) IsAudioUnpackable() bool { func (lc *LogicContext) IsAudioUnpackable() bool {
return lc.audioPayloadTypeBase == base.AvPacketPtAac && lc.Asc != nil switch lc.audioPayloadTypeBase {
case base.AvPacketPtAac:
if lc.Asc == nil {
return false
}
case base.AvPacketPtG711A:
return true
}
return false
} }
func (lc *LogicContext) IsVideoUnpackable() bool { func (lc *LogicContext) IsVideoUnpackable() bool {
@ -125,8 +134,22 @@ func ParseSdp2LogicContext(b []byte) (LogicContext, error) {
} else { } else {
Log.Warnf("aac afmtp not exist.") Log.Warnf("aac afmtp not exist.")
} }
} else if strings.EqualFold(md.ARtpMap.EncodingName, ARtpMapEncodingNameG711A) {
// 例子:a=rtpmap:8 PCMA/8000/1
// rtmpmap中有PCMA字段表示G711A
ret.audioPayloadTypeBase = base.AvPacketPtG711A
} else { } else {
ret.audioPayloadTypeBase = base.AvPacketPtUnknown if md.M.PT == 8 {
// ffmpeg推流情况下不会填充rtpmap字段,m中pt值为8也可以表示是PCMA,采样率默认为8000Hz
// RFC3551中表明G711A固定pt值为8
ret.audioPayloadTypeBase = base.AvPacketPtG711A
ret.audioPayloadTypeOrigin = 8
if ret.AudioClockRate == 0 {
ret.AudioClockRate = 8000
}
} else {
ret.audioPayloadTypeBase = base.AvPacketPtUnknown
}
} }
case "video": case "video":
ret.hasVideo = true ret.hasVideo = true

@ -29,6 +29,7 @@ type MediaDesc struct {
type M struct { type M struct {
Media string Media string
PT int // 暂时只支持m只有一个pt值的情况
} }
type ARtpMap struct { type ARtpMap struct {
@ -88,6 +89,7 @@ func ParseM(s string) (ret M, err error) {
return ret, nazaerrors.Wrap(base.ErrSdp) return ret, nazaerrors.Wrap(base.ErrSdp)
} }
ret.Media = items[0] ret.Media = items[0]
ret.PT, _ = strconv.Atoi(items[3])
return return
} }

@ -11,7 +11,8 @@ package sdp
// rfc4566 // rfc4566
const ( const (
ARtpMapEncodingNameH265 = "H265" ARtpMapEncodingNameH265 = "H265"
ARtpMapEncodingNameH264 = "H264" ARtpMapEncodingNameH264 = "H264"
ARtpMapEncodingNameAac = "MPEG4-GENERIC" ARtpMapEncodingNameAac = "MPEG4-GENERIC"
ARtpMapEncodingNameG711A = "PCMA"
) )

Loading…
Cancel
Save