From 9d61f04b62c32f5d19dccf70960da50b72d949e0 Mon Sep 17 00:00:00 2001 From: q191201771 <191201771@qq.com> Date: Sat, 15 May 2021 19:09:12 +0800 Subject: [PATCH] =?UTF-8?q?[feat]=20package=20rtprtcp:=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0RTPPackerAVC=EF=BC=8C=E7=94=A8=E4=BA=8E=E5=B0=86h264?= =?UTF-8?q?=20Nalu=E5=8C=85=E5=88=87=E5=89=B2=E6=88=90RTP=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/rtprtcp/rtp_packer_avc.go | 87 +++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 pkg/rtprtcp/rtp_packer_avc.go diff --git a/pkg/rtprtcp/rtp_packer_avc.go b/pkg/rtprtcp/rtp_packer_avc.go new file mode 100644 index 0000000..3b457e2 --- /dev/null +++ b/pkg/rtprtcp/rtp_packer_avc.go @@ -0,0 +1,87 @@ +// Copyright 2021, Chef. All rights reserved. +// https://github.com/q191201771/lal +// +// Use of this source code is governed by a MIT-style license +// that can be found in the License file. +// +// Author: Chef (191201771@qq.com) + +package rtprtcp + +import "github.com/q191201771/lal/pkg/avc" + +const ( + fuaHeaderSize = 2 +) + +type RTPPackerAVC struct { +} + +// @param nalu: AVCC格式 +// +// @return 返回RTP(only body)的数组 +// 内存块为独立申请,函数返回后,内部不再持有该内存块 +// +func (*RTPPackerAVC) Pack(nalu []byte, maxSize int) (ret [][]byte) { + if nalu == nil || maxSize <= 0 { + return + } + + nals, err := avc.IterateNALUAVCC(nalu) + if err != nil { + return + } + + for _, nal := range nals { + nalType := nal[0] & 0x1F + nri := nal[0] & 0x60 + + if nalType == avc.NALUTypeAUD { + continue + } + + // single + if len(nal) <= maxSize-fuaHeaderSize { + item := make([]byte, len(nal)) + copy(item, nal) + ret = append(ret, item) + continue + } + + // FU-A + var length int + bpos := 0 + epos := len(nal) + for { + if epos-bpos > maxSize-fuaHeaderSize { + // 前面的包 + length = maxSize + item := make([]byte, maxSize) + // fuIndicator + item[0] = NALUTypeAVCFUA + item[0] |= nri + // fuHeader + item[1] = nalType + if bpos == 0 { + item[1] |= 0x80 // start + } + // + copy(item[fuaHeaderSize:], nal[bpos:bpos+maxSize-fuaHeaderSize]) + bpos += maxSize - fuaHeaderSize + continue + } + + // 最后一包 + length = epos - bpos + fuaHeaderSize + item := make([]byte, length) + // fuIndicator + item[0] = NALUTypeAVCFUA + item[0] |= nri + // fuHeader + item[1] = nalType | 0x40 // end + copy(item[fuaHeaderSize:], nal[bpos:]) + break + } + } + return +}