g711.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. package track
  2. import (
  3. "io"
  4. "go.uber.org/zap"
  5. "m7s.live/engine/v4/codec"
  6. . "m7s.live/engine/v4/common"
  7. "m7s.live/engine/v4/util"
  8. )
  9. var _ SpesificTrack = (*G711)(nil)
  10. func NewG711(stream IStream, alaw bool, stuff ...any) (g711 *G711) {
  11. g711 = &G711{}
  12. if alaw {
  13. g711.Name = "pcma"
  14. g711.PayloadType = 8
  15. } else {
  16. g711.Name = "pcmu"
  17. g711.PayloadType = 0
  18. }
  19. if alaw {
  20. g711.CodecID = codec.CodecID_PCMA
  21. } else {
  22. g711.CodecID = codec.CodecID_PCMU
  23. }
  24. g711.SampleSize = 8
  25. g711.Channels = 1
  26. g711.AVCCHead = []byte{(byte(g711.CodecID) << 4) | (1 << 1)}
  27. g711.SetStuff(uint32(8000), g711, stuff, stream)
  28. if g711.BytesPool == nil {
  29. g711.BytesPool = make(util.BytesPool, 17)
  30. }
  31. go g711.Attach()
  32. return
  33. }
  34. type G711 struct {
  35. Audio
  36. }
  37. func (g711 *G711) WriteAVCC(ts uint32, frame *util.BLL) error {
  38. if l := frame.ByteLength; l < 2 {
  39. g711.Error("AVCC data too short", zap.Int("len", l))
  40. return io.ErrShortWrite
  41. }
  42. i := 0
  43. frame.Range(func(v util.Buffer) bool {
  44. if i == 0 {
  45. v = v.SubBuf(1, v.Len()-1)
  46. }
  47. g711.Value.AUList.Push(g711.BytesPool.GetShell(v))
  48. i++
  49. return true
  50. })
  51. g711.Audio.WriteAVCC(ts, frame)
  52. return nil
  53. }
  54. func (g711 *G711) WriteRTPFrame(rtpItem *util.ListItem[RTPFrame]) {
  55. frame := &rtpItem.Value
  56. g711.Value.RTP.Push(rtpItem)
  57. if g711.SampleRate != 90000 {
  58. g711.generateTimestamp(uint32(uint64(frame.Timestamp) * 90000 / uint64(g711.SampleRate)))
  59. }
  60. g711.AppendAuBytes(frame.Payload)
  61. g711.Flush()
  62. }
  63. func (g711 *G711) CompleteRTP(value *AVFrame) {
  64. if value.AUList.ByteLength > RTPMTU {
  65. var packets [][][]byte
  66. r := value.AUList.Next.Value.NewReader()
  67. for bufs := r.ReadN(RTPMTU); len(bufs) > 0; bufs = r.ReadN(RTPMTU) {
  68. packets = append(packets, bufs)
  69. }
  70. g711.PacketizeRTP(packets...)
  71. } else {
  72. g711.Audio.CompleteRTP(value)
  73. }
  74. }