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