mirror of
https://github.com/Monibuca/engine.git
synced 2025-10-06 09:06:52 +08:00
优化代码
This commit is contained in:
@@ -4,51 +4,52 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Monibuca/engine/v4/codec"
|
|
||||||
"github.com/Monibuca/engine/v4/util"
|
"github.com/Monibuca/engine/v4/util"
|
||||||
"github.com/pion/rtp"
|
"github.com/pion/rtp"
|
||||||
)
|
)
|
||||||
|
|
||||||
type NALUSlice net.Buffers
|
type NALUSlice net.Buffers
|
||||||
type H264Slice NALUSlice
|
// type H264Slice NALUSlice
|
||||||
type H265Slice NALUSlice
|
// type H265Slice NALUSlice
|
||||||
|
|
||||||
type H264NALU []NALUSlice
|
// type H264NALU []H264Slice
|
||||||
type H265NALU []NALUSlice
|
// type H265NALU []H265Slice
|
||||||
|
|
||||||
type AudioSlice []byte
|
type AudioSlice []byte
|
||||||
type AACSlice AudioSlice
|
|
||||||
type G711Slice AudioSlice
|
// type AACSlice AudioSlice
|
||||||
|
// type G711Slice AudioSlice
|
||||||
|
|
||||||
// 裸数据片段
|
// 裸数据片段
|
||||||
type RawSlice interface {
|
type RawSlice interface {
|
||||||
NALUSlice | AudioSlice
|
~[][]byte | ~[]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (nalu *H264NALU) Append(slice ...NALUSlice) {
|
// func (nalu *H264NALU) Append(slice ...NALUSlice) {
|
||||||
*nalu = append(*nalu, slice...)
|
// *nalu = append(*nalu, slice...)
|
||||||
}
|
// }
|
||||||
func (nalu H264Slice) Type() byte {
|
func (nalu NALUSlice) H264Type() byte {
|
||||||
return nalu[0][0] & 0x1F
|
return nalu[0][0] & 0x1F
|
||||||
}
|
}
|
||||||
func (nalu H265Slice) Type() byte {
|
func (nalu NALUSlice) H265Type() byte {
|
||||||
return nalu[0][0] & 0x7E >> 1
|
return nalu[0][0] & 0x7E >> 1
|
||||||
}
|
}
|
||||||
func (nalu *H265NALU) Append(slice ...NALUSlice) {
|
|
||||||
*nalu = append(*nalu, slice...)
|
// func (nalu *H265NALU) Append(slice ...NALUSlice) {
|
||||||
}
|
// *nalu = append(*nalu, slice...)
|
||||||
func (nalu H265NALU) IFrame() bool {
|
// }
|
||||||
switch H265Slice(nalu[0]).Type() {
|
// func (nalu H265NALU) IFrame() bool {
|
||||||
case codec.NAL_UNIT_CODED_SLICE_BLA,
|
// switch H265Slice(nalu[0]).Type() {
|
||||||
codec.NAL_UNIT_CODED_SLICE_BLANT,
|
// case codec.NAL_UNIT_CODED_SLICE_BLA,
|
||||||
codec.NAL_UNIT_CODED_SLICE_BLA_N_LP,
|
// codec.NAL_UNIT_CODED_SLICE_BLANT,
|
||||||
codec.NAL_UNIT_CODED_SLICE_IDR,
|
// codec.NAL_UNIT_CODED_SLICE_BLA_N_LP,
|
||||||
codec.NAL_UNIT_CODED_SLICE_IDR_N_LP,
|
// codec.NAL_UNIT_CODED_SLICE_IDR,
|
||||||
codec.NAL_UNIT_CODED_SLICE_CRA:
|
// codec.NAL_UNIT_CODED_SLICE_IDR_N_LP,
|
||||||
return true
|
// codec.NAL_UNIT_CODED_SLICE_CRA:
|
||||||
}
|
// return true
|
||||||
return false
|
// }
|
||||||
}
|
// return false
|
||||||
|
// }
|
||||||
|
|
||||||
type AVCCFrame []byte // 一帧AVCC格式的数据
|
type AVCCFrame []byte // 一帧AVCC格式的数据
|
||||||
type AnnexBFrame []byte // 一帧AnnexB格式数据
|
type AnnexBFrame []byte // 一帧AnnexB格式数据
|
||||||
@@ -81,15 +82,14 @@ func (av *AVFrame[T]) AppendRaw(raw ...T) {
|
|||||||
av.Raw = append(av.Raw, raw...)
|
av.Raw = append(av.Raw, raw...)
|
||||||
}
|
}
|
||||||
func (av *AVFrame[T]) FillFLV(t byte, ts uint32) {
|
func (av *AVFrame[T]) FillFLV(t byte, ts uint32) {
|
||||||
b := make([]byte, 15)
|
b := util.Buffer(make([]byte, 0, 15))
|
||||||
b[0] = t
|
b.WriteByte(t)
|
||||||
dataSize := util.SizeOfBuffers(av.AVCC)
|
dataSize := util.SizeOfBuffers(av.AVCC)
|
||||||
util.PutBE(b[1:4], dataSize)
|
b.WriteUint24(uint32(dataSize))
|
||||||
util.PutBE(b[4:7], ts)
|
b.WriteUint24(ts)
|
||||||
b[7] = byte(ts >> 24)
|
b.WriteByte(byte(ts >> 24))
|
||||||
av.FLV = append(av.FLV, b[:11])
|
b.WriteUint24(0)
|
||||||
av.FLV = append(av.FLV, av.AVCC...)
|
av.FLV = append(append(append(av.FLV, b), av.AVCC...), util.PutBE(b.Malloc(4), dataSize+11))
|
||||||
av.FLV = append(av.FLV, util.PutBE(b[11:15], dataSize+11))
|
|
||||||
}
|
}
|
||||||
func (av *AVFrame[T]) AppendAVCC(avcc ...[]byte) {
|
func (av *AVFrame[T]) AppendAVCC(avcc ...[]byte) {
|
||||||
av.AVCC = append(av.AVCC, avcc...)
|
av.AVCC = append(av.AVCC, avcc...)
|
||||||
|
@@ -25,13 +25,3 @@ func (bps *BPS) ComputeBPS(bytes int) {
|
|||||||
bps.ts = time.Now()
|
bps.ts = time.Now()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type HZ uint32
|
|
||||||
|
|
||||||
func (hz HZ) ToMini(nts uint32) uint32 {
|
|
||||||
return nts / (uint32(hz) / 1000)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (hz HZ) ToNTS(mini uint32) uint32 {
|
|
||||||
return mini * (uint32(hz) / 1000)
|
|
||||||
}
|
|
||||||
|
@@ -256,14 +256,18 @@ func (r *Stream) NewAudioTrack() (at *track.UnknowAudio) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (r *Stream) NewH264Track() (vt *track.H264) {
|
func (r *Stream) NewH264Track() *track.H264 {
|
||||||
return track.NewH264(r)
|
return track.NewH264(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Stream) NewH265Track() (vt *track.H265) {
|
func (r *Stream) NewH265Track() *track.H265 {
|
||||||
return track.NewH265(r)
|
return track.NewH265(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Stream) NewAACTrack() *track.AAC {
|
||||||
|
return track.NewAAC(r)
|
||||||
|
}
|
||||||
|
|
||||||
// func (r *Stream) WaitDataTrack(names ...string) DataTrack {
|
// func (r *Stream) WaitDataTrack(names ...string) DataTrack {
|
||||||
// t := <-r.WaitTrack(names...)
|
// t := <-r.WaitTrack(names...)
|
||||||
// return t.(DataTrack)
|
// return t.(DataTrack)
|
||||||
|
@@ -30,7 +30,7 @@ func (aac *AAC) WriteAVCC(ts uint32, frame AVCCFrame) {
|
|||||||
// 3 AAC SSR ISO/IEC 14496-3 subpart 4
|
// 3 AAC SSR ISO/IEC 14496-3 subpart 4
|
||||||
// 4 AAC LTP ISO/IEC 14496-3 subpart 4
|
// 4 AAC LTP ISO/IEC 14496-3 subpart 4
|
||||||
aac.Channels = ((config2 >> 3) & 0x0F) //声道
|
aac.Channels = ((config2 >> 3) & 0x0F) //声道
|
||||||
aac.SampleRate = HZ(codec.SamplingFrequencies[((config1&0x7)<<1)|(config2>>7)])
|
aac.SampleRate = uint32(codec.SamplingFrequencies[((config1&0x7)<<1)|(config2>>7)])
|
||||||
aac.DecoderConfiguration.AppendRaw(AudioSlice(frame[2:]))
|
aac.DecoderConfiguration.AppendRaw(AudioSlice(frame[2:]))
|
||||||
aac.DecoderConfiguration.FillFLV(codec.FLV_TAG_TYPE_AUDIO, 0)
|
aac.DecoderConfiguration.FillFLV(codec.FLV_TAG_TYPE_AUDIO, 0)
|
||||||
} else {
|
} else {
|
||||||
|
@@ -35,7 +35,13 @@ func (at *Audio) Play(onAudio func(*AVFrame[AudioSlice]) error) {
|
|||||||
ar.MoveNext()
|
ar.MoveNext()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
func (at *Audio) WriteADTS(adts []byte) {
|
||||||
|
at.SampleRate = uint32(codec.SamplingFrequencies[(adts[2]&0x3c)>>2])
|
||||||
|
at.Channels = ((adts[2] & 0x1) << 2) | ((adts[3] & 0xc0) >> 6)
|
||||||
|
at.DecoderConfiguration.AppendAVCC(codec.ADTSToAudioSpecificConfig(adts))
|
||||||
|
at.DecoderConfiguration.AppendRaw(at.DecoderConfiguration.AVCC[0][2:])
|
||||||
|
at.DecoderConfiguration.FillFLV(codec.FLV_TAG_TYPE_AUDIO, 0)
|
||||||
|
}
|
||||||
func (at *Audio) WriteAVCC(ts uint32, frame AVCCFrame) {
|
func (at *Audio) WriteAVCC(ts uint32, frame AVCCFrame) {
|
||||||
at.Media.WriteAVCC(ts, frame)
|
at.Media.WriteAVCC(ts, frame)
|
||||||
at.Flush()
|
at.Flush()
|
||||||
@@ -50,7 +56,7 @@ func (at *Audio) Flush() {
|
|||||||
}
|
}
|
||||||
// FLV tag 补完
|
// FLV tag 补完
|
||||||
if at.Value.FLV == nil {
|
if at.Value.FLV == nil {
|
||||||
at.Value.FillFLV(codec.FLV_TAG_TYPE_AUDIO, at.SampleRate.ToMini(at.Value.DTS))
|
at.Value.FillFLV(codec.FLV_TAG_TYPE_AUDIO, at.Value.DTS/90)
|
||||||
}
|
}
|
||||||
at.Media.Flush()
|
at.Media.Flush()
|
||||||
}
|
}
|
||||||
@@ -86,7 +92,7 @@ func (at *UnknowAudio) WriteAVCC(ts uint32, frame AVCCFrame) {
|
|||||||
}
|
}
|
||||||
a := NewG711(at.Stream, alaw)
|
a := NewG711(at.Stream, alaw)
|
||||||
at.Know = a
|
at.Know = a
|
||||||
a.SampleRate = HZ(codec.SoundRate[(frame[0]&0x0c)>>2])
|
a.SampleRate = uint32(codec.SoundRate[(frame[0]&0x0c)>>2])
|
||||||
a.SampleSize = 16
|
a.SampleSize = 16
|
||||||
if frame[0]&0x02 == 0 {
|
if frame[0]&0x02 == 0 {
|
||||||
a.SampleSize = 8
|
a.SampleSize = 8
|
||||||
|
@@ -27,7 +27,7 @@ type Media[T RawSlice] struct {
|
|||||||
Base
|
Base
|
||||||
AVRing[T] `json:"-"`
|
AVRing[T] `json:"-"`
|
||||||
CodecID byte
|
CodecID byte
|
||||||
SampleRate HZ
|
SampleRate uint32
|
||||||
SampleSize byte
|
SampleSize byte
|
||||||
DecoderConfiguration AVFrame[T] `json:"-"` //H264(SPS、PPS) H265(VPS、SPS、PPS) AAC(config)
|
DecoderConfiguration AVFrame[T] `json:"-"` //H264(SPS、PPS) H265(VPS、SPS、PPS) AAC(config)
|
||||||
util.BytesPool //无锁内存池,用于发布者(在同一个协程中)复用小块的内存,通常是解包时需要临时使用
|
util.BytesPool //无锁内存池,用于发布者(在同一个协程中)复用小块的内存,通常是解包时需要临时使用
|
||||||
@@ -49,6 +49,7 @@ func (av *Media[T]) WriteRTP(raw []byte) {
|
|||||||
func (av *Media[T]) WriteSlice(slice T) {
|
func (av *Media[T]) WriteSlice(slice T) {
|
||||||
av.Value.AppendRaw(slice)
|
av.Value.AppendRaw(slice)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (av *Media[T]) WriteAVCC(ts uint32, frame AVCCFrame) {
|
func (av *Media[T]) WriteAVCC(ts uint32, frame AVCCFrame) {
|
||||||
if av.lastAvccTS == 0 {
|
if av.lastAvccTS == 0 {
|
||||||
av.lastAvccTS = ts
|
av.lastAvccTS = ts
|
||||||
@@ -57,8 +58,8 @@ func (av *Media[T]) WriteAVCC(ts uint32, frame AVCCFrame) {
|
|||||||
}
|
}
|
||||||
av.Value.BytesIn = len(frame)
|
av.Value.BytesIn = len(frame)
|
||||||
av.Value.AppendAVCC(frame)
|
av.Value.AppendAVCC(frame)
|
||||||
av.Value.DTS = av.SampleRate.ToNTS(ts)
|
av.Value.DTS = ts * 90
|
||||||
av.Value.PTS = av.SampleRate.ToNTS(ts + frame.CTS())
|
av.Value.PTS = (ts + frame.CTS()) * 90
|
||||||
}
|
}
|
||||||
|
|
||||||
func (av *Media[T]) Flush() {
|
func (av *Media[T]) Flush() {
|
||||||
|
@@ -26,7 +26,7 @@ func (vt *H264) WriteAnnexB(pts uint32, dts uint32, frame AnnexBFrame) {
|
|||||||
vt.Flush()
|
vt.Flush()
|
||||||
}
|
}
|
||||||
func (vt *H264) WriteSlice(slice NALUSlice) {
|
func (vt *H264) WriteSlice(slice NALUSlice) {
|
||||||
switch H264Slice(slice).Type() {
|
switch slice.H264Type() {
|
||||||
case codec.NALU_SPS:
|
case codec.NALU_SPS:
|
||||||
vt.DecoderConfiguration.Reset()
|
vt.DecoderConfiguration.Reset()
|
||||||
vt.DecoderConfiguration.AppendRaw(slice)
|
vt.DecoderConfiguration.AppendRaw(slice)
|
||||||
|
@@ -24,7 +24,7 @@ func (vt *H265) WriteAnnexB(pts uint32, dts uint32, frame AnnexBFrame) {
|
|||||||
vt.Flush()
|
vt.Flush()
|
||||||
}
|
}
|
||||||
func (vt *H265) WriteSlice(slice NALUSlice) {
|
func (vt *H265) WriteSlice(slice NALUSlice) {
|
||||||
switch H265Slice(slice).Type() {
|
switch slice.H265Type() {
|
||||||
case codec.NAL_UNIT_VPS:
|
case codec.NAL_UNIT_VPS:
|
||||||
vt.DecoderConfiguration.Reset()
|
vt.DecoderConfiguration.Reset()
|
||||||
vt.DecoderConfiguration.AppendRaw(slice)
|
vt.DecoderConfiguration.AppendRaw(slice)
|
||||||
|
@@ -99,7 +99,7 @@ func (vt *Video) Flush() {
|
|||||||
b[0] |= 0x20
|
b[0] |= 0x20
|
||||||
}
|
}
|
||||||
// 写入CTS
|
// 写入CTS
|
||||||
util.PutBE(b[2:5], vt.SampleRate.ToMini(vt.Value.PTS-vt.Value.DTS))
|
util.PutBE(b[2:5], (vt.Value.PTS-vt.Value.DTS)/90)
|
||||||
vt.Value.AppendAVCC(b)
|
vt.Value.AppendAVCC(b)
|
||||||
for _, nalu := range vt.Value.Raw {
|
for _, nalu := range vt.Value.Raw {
|
||||||
vt.Value.AppendAVCC(util.PutBE(make([]byte, 4), util.SizeOfBuffers(net.Buffers(nalu))))
|
vt.Value.AppendAVCC(util.PutBE(make([]byte, 4), util.SizeOfBuffers(net.Buffers(nalu))))
|
||||||
@@ -108,7 +108,7 @@ func (vt *Video) Flush() {
|
|||||||
}
|
}
|
||||||
// FLV tag 补完
|
// FLV tag 补完
|
||||||
if vt.Value.FLV == nil {
|
if vt.Value.FLV == nil {
|
||||||
vt.Value.FillFLV(codec.FLV_TAG_TYPE_VIDEO, vt.SampleRate.ToMini(vt.Value.DTS))
|
vt.Value.FillFLV(codec.FLV_TAG_TYPE_VIDEO, vt.Value.DTS/90)
|
||||||
}
|
}
|
||||||
// 下一帧为I帧,即将覆盖
|
// 下一帧为I帧,即将覆盖
|
||||||
if vt.Next().Value.IFrame {
|
if vt.Next().Value.IFrame {
|
||||||
|
@@ -44,7 +44,7 @@ func (b *Buffer) WriteUint24(v uint32) {
|
|||||||
func (b *Buffer) WriteUint16(v uint16) {
|
func (b *Buffer) WriteUint16(v uint16) {
|
||||||
binary.BigEndian.PutUint16(b.Malloc(2), v)
|
binary.BigEndian.PutUint16(b.Malloc(2), v)
|
||||||
}
|
}
|
||||||
func (b *Buffer) WriteUint8(v byte) {
|
func (b *Buffer) WriteByte(v byte) {
|
||||||
b.Malloc(1)[0] = v
|
b.Malloc(1)[0] = v
|
||||||
}
|
}
|
||||||
func (b *Buffer) WriteString(a string) {
|
func (b *Buffer) WriteString(a string) {
|
||||||
|
Reference in New Issue
Block a user