fix: sub rtp audio panic

This commit is contained in:
langhuihui
2025-09-05 09:29:58 +08:00
parent 7bc993a9ed
commit 93bcdfbec2
5 changed files with 21 additions and 31 deletions

View File

@@ -140,11 +140,11 @@ func (b *BaseSample) GetCTS32() uint32 {
return uint32(b.CTS / time.Millisecond) return uint32(b.CTS / time.Millisecond)
} }
func (b *BaseSample) GetNalus() *util.ReuseArray[util.Memory] { func (b *BaseSample) GetNalus() *Nalus {
if b.Raw == nil { if b.Raw == nil {
b.Raw = &Nalus{} b.Raw = &Nalus{}
} }
return b.Raw.(*util.ReuseArray[util.Memory]) return b.Raw.(*Nalus)
} }
func (b *BaseSample) GetAudioData() *AudioData { func (b *BaseSample) GetAudioData() *AudioData {

View File

@@ -114,9 +114,11 @@ func (s *ReuseArray[T]) Reduce() ReuseArray[T] {
} }
func (s *ReuseArray[T]) Remove(item *T) bool { func (s *ReuseArray[T]) Remove(item *T) bool {
for i := range *s { count := s.Count()
for i := range count {
if &(*s)[i] == item { if &(*s)[i] == item {
*s = append((*s)[:i], (*s)[i+1:]...) *s = append((*s)[:i], (*s)[i+1:]...)
*s = append(*s, *item)[:count-1]
return true return true
} }
} }

View File

@@ -286,8 +286,8 @@ func (avcc *VideoFrame) Demux() error {
} }
func (avcc *VideoFrame) muxOld26x(codecID VideoCodecID, fromBase *Sample) { func (avcc *VideoFrame) muxOld26x(codecID VideoCodecID, fromBase *Sample) {
nalus := fromBase.Raw.(*Nalus) nalus := fromBase.GetNalus()
avcc.InitRecycleIndexes(len(*nalus)) // Recycle partial data avcc.InitRecycleIndexes(nalus.Count()) // Recycle partial data
head := avcc.NextN(5) head := avcc.NextN(5)
head[0] = util.Conditional[byte](fromBase.IDR, 0x10, 0x20) | byte(codecID) head[0] = util.Conditional[byte](fromBase.IDR, 0x10, 0x20) | byte(codecID)
head[1] = 1 head[1] = 1
@@ -296,6 +296,9 @@ func (avcc *VideoFrame) muxOld26x(codecID VideoCodecID, fromBase *Sample) {
naluLenM := avcc.NextN(4) naluLenM := avcc.NextN(4)
naluLen := uint32(nalu.Size) naluLen := uint32(nalu.Size)
binary.BigEndian.PutUint32(naluLenM, naluLen) binary.BigEndian.PutUint32(naluLenM, naluLen)
if nalu.Size != len(util.ConcatBuffers(nalu.Buffers)) {
panic("nalu size mismatch")
}
avcc.Push(nalu.Buffers...) avcc.Push(nalu.Buffers...)
} }
} }

View File

@@ -320,9 +320,8 @@ func (r *AudioFrame) Mux(from *Sample) (err error) {
ctx.PayloadType = 8 ctx.PayloadType = 8
ctx.ClockRate = uint32(ctx.SampleRate) ctx.ClockRate = uint32(ctx.SampleRate)
r.ICodecCtx = &ctx r.ICodecCtx = &ctx
} else {
ctx = &r.ICodecCtx.(*PCMACtx).RTPCtx
} }
ctx = &r.ICodecCtx.(*PCMACtx).RTPCtx
case *codec.PCMUCtx: case *codec.PCMUCtx:
if r.ICodecCtx == nil { if r.ICodecCtx == nil {
var ctx PCMUCtx var ctx PCMUCtx
@@ -332,9 +331,8 @@ func (r *AudioFrame) Mux(from *Sample) (err error) {
ctx.PayloadType = 0 ctx.PayloadType = 0
ctx.ClockRate = uint32(ctx.SampleRate) ctx.ClockRate = uint32(ctx.SampleRate)
r.ICodecCtx = &ctx r.ICodecCtx = &ctx
} else {
ctx = &r.ICodecCtx.(*PCMUCtx).RTPCtx
} }
ctx = &r.ICodecCtx.(*PCMUCtx).RTPCtx
} }
pts := uint32(from.Timestamp * time.Duration(ctx.ClockRate) / time.Second) pts := uint32(from.Timestamp * time.Duration(ctx.ClockRate) / time.Second)
if reader := data.NewReader(); reader.Length > MTUSize { if reader := data.NewReader(); reader.Length > MTUSize {

View File

@@ -61,12 +61,6 @@ const (
MTUSize = 1460 MTUSize = 1460
) )
func (r *VideoFrame) Parse(data IAVFrame) (err error) {
input := data.(*VideoFrame)
r.Packets = append(r.Packets[:0], input.Packets...)
return
}
func (r *VideoFrame) Recycle() { func (r *VideoFrame) Recycle() {
r.RecyclableMemory.Recycle() r.RecyclableMemory.Recycle()
r.Packets.Reset() r.Packets.Reset()
@@ -98,10 +92,10 @@ func (r *VideoFrame) CheckCodecChange() (err error) {
switch nalType { switch nalType {
case h264parser.NALU_SPS: case h264parser.NALU_SPS:
sps = nalu.ToBytes() sps = nalu.ToBytes()
defer nalus.Remove(nalu) //TODO: defer nalus.Remove(nalu)
case h264parser.NALU_PPS: case h264parser.NALU_PPS:
pps = nalu.ToBytes() pps = nalu.ToBytes()
defer nalus.Remove(nalu) //TODO: defer nalus.Remove(nalu)
case codec.NALU_IDR_Picture: case codec.NALU_IDR_Picture:
r.IDR = true r.IDR = true
} }
@@ -377,13 +371,8 @@ func (r *VideoFrame) Demux() (err error) {
switch c := r.ICodecCtx.(type) { switch c := r.ICodecCtx.(type) {
case *H264Ctx: case *H264Ctx:
nalus := r.GetNalus() nalus := r.GetNalus()
nalu := nalus.GetNextPointer() var nalu *util.Memory
var naluType codec.H264NALUType var naluType codec.H264NALUType
gotNalu := func() {
if nalu.Size > 0 {
nalu = nalus.GetNextPointer()
}
}
for packet := range r.Packets.RangePoint { for packet := range r.Packets.RangePoint {
if len(packet.Payload) < 2 { if len(packet.Payload) < 2 {
continue continue
@@ -393,8 +382,7 @@ func (r *VideoFrame) Demux() (err error) {
} }
b0 := packet.Payload[0] b0 := packet.Payload[0]
if t := codec.ParseH264NALUType(b0); t < 24 { if t := codec.ParseH264NALUType(b0); t < 24 {
nalu.PushOne(packet.Payload) nalus.GetNextPointer().PushOne(packet.Payload)
gotNalu()
} else { } else {
offset := t.Offset() offset := t.Offset()
switch t { switch t {
@@ -404,8 +392,7 @@ func (r *VideoFrame) Demux() (err error) {
} }
for buffer := util.Buffer(packet.Payload[offset:]); buffer.CanRead(); { for buffer := util.Buffer(packet.Payload[offset:]); buffer.CanRead(); {
if nextSize := int(buffer.ReadUint16()); buffer.Len() >= nextSize { if nextSize := int(buffer.ReadUint16()); buffer.Len() >= nextSize {
nalu.PushOne(buffer.ReadN(nextSize)) nalus.GetNextPointer().PushOne(buffer.ReadN(nextSize))
gotNalu()
} else { } else {
return fmt.Errorf("invalid nalu size %d", nextSize) return fmt.Errorf("invalid nalu size %d", nextSize)
} }
@@ -413,23 +400,23 @@ func (r *VideoFrame) Demux() (err error) {
case codec.NALU_FUA, codec.NALU_FUB: case codec.NALU_FUA, codec.NALU_FUB:
b1 := packet.Payload[1] b1 := packet.Payload[1]
if util.Bit1(b1, 0) { if util.Bit1(b1, 0) {
nalu = nalus.GetNextPointer()
naluType.Parse(b1) naluType.Parse(b1)
nalu.PushOne([]byte{naluType.Or(b0 & 0x60)}) nalu.PushOne([]byte{naluType.Or(b0 & 0x60)})
} }
if nalu.Size > 0 { if nalu.Size > 0 {
nalu.PushOne(packet.Payload[offset:]) nalu.PushOne(packet.Payload[offset:])
if util.Bit1(b1, 1) {
// 结束位
}
} else { } else {
continue continue
} }
if util.Bit1(b1, 1) {
gotNalu()
}
default: default:
return fmt.Errorf("unsupported nalu type %d", t) return fmt.Errorf("unsupported nalu type %d", t)
} }
} }
} }
nalus.Reduce()
return nil return nil
case *H265Ctx: case *H265Ctx:
nalus := r.GetNalus() nalus := r.GetNalus()