12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- package track
- import (
- "io"
- "go.uber.org/zap"
- "m7s.live/engine/v4/codec"
- . "m7s.live/engine/v4/common"
- "m7s.live/engine/v4/util"
- )
- var _ SpesificTrack = (*G711)(nil)
- func NewG711(stream IStream, alaw bool, stuff ...any) (g711 *G711) {
- g711 = &G711{}
- if alaw {
- g711.Name = "pcma"
- g711.PayloadType = 8
- } else {
- g711.Name = "pcmu"
- g711.PayloadType = 0
- }
- if alaw {
- g711.CodecID = codec.CodecID_PCMA
- } else {
- g711.CodecID = codec.CodecID_PCMU
- }
- g711.SampleSize = 8
- g711.Channels = 1
- g711.AVCCHead = []byte{(byte(g711.CodecID) << 4) | (1 << 1)}
- g711.SetStuff(uint32(8000), g711, stuff, stream)
- if g711.BytesPool == nil {
- g711.BytesPool = make(util.BytesPool, 17)
- }
- go g711.Attach()
- return
- }
- type G711 struct {
- Audio
- }
- func (g711 *G711) WriteAVCC(ts uint32, frame *util.BLL) error {
- if l := frame.ByteLength; l < 2 {
- g711.Error("AVCC data too short", zap.Int("len", l))
- return io.ErrShortWrite
- }
- i := 0
- frame.Range(func(v util.Buffer) bool {
- if i == 0 {
- v = v.SubBuf(1, v.Len()-1)
- }
- g711.Value.AUList.Push(g711.BytesPool.GetShell(v))
- i++
- return true
- })
- g711.Audio.WriteAVCC(ts, frame)
- return nil
- }
- func (g711 *G711) WriteRTPFrame(rtpItem *util.ListItem[RTPFrame]) {
- frame := &rtpItem.Value
- g711.Value.RTP.Push(rtpItem)
- if g711.SampleRate != 90000 {
- g711.generateTimestamp(uint32(uint64(frame.Timestamp) * 90000 / uint64(g711.SampleRate)))
- }
- g711.AppendAuBytes(frame.Payload)
- g711.Flush()
- }
- func (g711 *G711) CompleteRTP(value *AVFrame) {
- if value.AUList.ByteLength > RTPMTU {
- var packets [][][]byte
- r := value.AUList.Next.Value.NewReader()
- for bufs := r.ReadN(RTPMTU); len(bufs) > 0; bufs = r.ReadN(RTPMTU) {
- packets = append(packets, bufs)
- }
- g711.PacketizeRTP(packets...)
- } else {
- g711.Audio.CompleteRTP(value)
- }
- }
|