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)
}
func (b *BaseSample) GetNalus() *util.ReuseArray[util.Memory] {
func (b *BaseSample) GetNalus() *Nalus {
if b.Raw == nil {
b.Raw = &Nalus{}
}
return b.Raw.(*util.ReuseArray[util.Memory])
return b.Raw.(*Nalus)
}
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 {
for i := range *s {
count := s.Count()
for i := range count {
if &(*s)[i] == item {
*s = append((*s)[:i], (*s)[i+1:]...)
*s = append(*s, *item)[:count-1]
return true
}
}

View File

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

View File

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

View File

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