From ff381e7fbf9eb6ef44e93d9fdb1e84e963ce4268 Mon Sep 17 00:00:00 2001 From: dexter <178529795@qq.com> Date: Mon, 7 Feb 2022 22:27:45 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/frame.go | 72 ++++++++++++++++++++++++------------------------- common/index.go | 12 +-------- stream.go | 8 ++++-- track/aac.go | 2 +- track/audio.go | 12 ++++++--- track/base.go | 7 ++--- track/h264.go | 2 +- track/h265.go | 2 +- track/video.go | 4 +-- util/buffer.go | 2 +- 10 files changed, 62 insertions(+), 61 deletions(-) diff --git a/common/frame.go b/common/frame.go index ebb9159..3870e4d 100644 --- a/common/frame.go +++ b/common/frame.go @@ -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...) diff --git a/common/index.go b/common/index.go index c310afc..fef6fda 100644 --- a/common/index.go +++ b/common/index.go @@ -24,14 +24,4 @@ func (bps *BPS) ComputeBPS(bytes int) { bps.BPS = bps.bytes / int(elapse) 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) -} +} \ No newline at end of file diff --git a/stream.go b/stream.go index 8c4441f..f801792 100644 --- a/stream.go +++ b/stream.go @@ -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) diff --git a/track/aac.go b/track/aac.go index ae2cf30..c28e86b 100644 --- a/track/aac.go +++ b/track/aac.go @@ -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 { diff --git a/track/audio.go b/track/audio.go index 075621b..c3a255f 100644 --- a/track/audio.go +++ b/track/audio.go @@ -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 diff --git a/track/base.go b/track/base.go index 1cdd313..8c54574 100644 --- a/track/base.go +++ b/track/base.go @@ -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() { diff --git a/track/h264.go b/track/h264.go index 0ce67df..77c8079 100644 --- a/track/h264.go +++ b/track/h264.go @@ -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) diff --git a/track/h265.go b/track/h265.go index cdb1da3..6c67d69 100644 --- a/track/h265.go +++ b/track/h265.go @@ -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) diff --git a/track/video.go b/track/video.go index 6906c71..99c4978 100644 --- a/track/video.go +++ b/track/video.go @@ -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 { diff --git a/util/buffer.go b/util/buffer.go index b9a698e..9e3817f 100644 --- a/util/buffer.go +++ b/util/buffer.go @@ -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) {