ps-muxer.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. package mpeg2
  2. import "github.com/yapingcat/gomedia/codec"
  3. type PSMuxer struct {
  4. system *System_header
  5. psm *Program_stream_map
  6. OnPacket func(pkg []byte)
  7. firstframe bool
  8. }
  9. func NewPsMuxer() *PSMuxer {
  10. muxer := new(PSMuxer)
  11. muxer.firstframe = true
  12. muxer.system = new(System_header)
  13. muxer.system.Rate_bound = 26234
  14. muxer.psm = new(Program_stream_map)
  15. muxer.psm.Current_next_indicator = 1
  16. muxer.psm.Program_stream_map_version = 1
  17. muxer.OnPacket = nil
  18. return muxer
  19. }
  20. func (muxer *PSMuxer) AddStream(cid PS_STREAM_TYPE) uint8 {
  21. if cid == PS_STREAM_H265 || cid == PS_STREAM_H264 {
  22. es := NewElementary_Stream(uint8(PES_STREAM_VIDEO) + muxer.system.Video_bound)
  23. es.P_STD_buffer_bound_scale = 1
  24. es.P_STD_buffer_size_bound = 400
  25. muxer.system.Streams = append(muxer.system.Streams, es)
  26. muxer.system.Video_bound++
  27. muxer.psm.Stream_map = append(muxer.psm.Stream_map, NewElementary_stream_elem(uint8(cid), es.Stream_id))
  28. muxer.psm.Program_stream_map_version++
  29. return es.Stream_id
  30. } else {
  31. es := NewElementary_Stream(uint8(PES_STREAM_AUDIO) + muxer.system.Audio_bound)
  32. es.P_STD_buffer_bound_scale = 0
  33. es.P_STD_buffer_size_bound = 32
  34. muxer.system.Streams = append(muxer.system.Streams, es)
  35. muxer.system.Audio_bound++
  36. muxer.psm.Stream_map = append(muxer.psm.Stream_map, NewElementary_stream_elem(uint8(cid), es.Stream_id))
  37. muxer.psm.Program_stream_map_version++
  38. return es.Stream_id
  39. }
  40. }
  41. func (muxer *PSMuxer) Write(sid uint8, frame []byte, pts uint64, dts uint64) error {
  42. var stream *Elementary_stream_elem = nil
  43. for _, es := range muxer.psm.Stream_map {
  44. if es.Elementary_stream_id == sid {
  45. stream = es
  46. break
  47. }
  48. }
  49. if stream == nil {
  50. return errNotFound
  51. }
  52. var withaud bool = false
  53. var idr_flag bool = false
  54. var first bool = true
  55. var vcl bool = false
  56. if stream.Stream_type == uint8(PS_STREAM_H264) || stream.Stream_type == uint8(PS_STREAM_H265) {
  57. codec.SplitFrame(frame, func(nalu []byte) bool {
  58. if stream.Stream_type == uint8(PS_STREAM_H264) {
  59. nalu_type := codec.H264NaluTypeWithoutStartCode(nalu)
  60. if nalu_type == codec.H264_NAL_AUD {
  61. withaud = true
  62. return false
  63. } else if codec.IsH264VCLNaluType(nalu_type) {
  64. if nalu_type == codec.H264_NAL_I_SLICE {
  65. idr_flag = true
  66. }
  67. vcl = true
  68. return false
  69. }
  70. return true
  71. } else {
  72. nalu_type := codec.H265NaluTypeWithoutStartCode(nalu)
  73. if nalu_type == codec.H265_NAL_AUD {
  74. withaud = true
  75. return false
  76. } else if codec.IsH265VCLNaluType(nalu_type) {
  77. if nalu_type >= codec.H265_NAL_SLICE_BLA_W_LP && nalu_type <= codec.H265_NAL_SLICE_CRA {
  78. idr_flag = true
  79. }
  80. vcl = true
  81. return false
  82. }
  83. return true
  84. }
  85. })
  86. }
  87. dts = dts * 90
  88. pts = pts * 90
  89. bsw := codec.NewBitStreamWriter(1024)
  90. var pack PSPackHeader
  91. pack.System_clock_reference_base = dts - 3600
  92. pack.System_clock_reference_extension = 0
  93. pack.Program_mux_rate = 6106
  94. pack.Encode(bsw)
  95. if muxer.firstframe || idr_flag {
  96. muxer.system.Encode(bsw)
  97. muxer.psm.Encode(bsw)
  98. muxer.firstframe = false
  99. }
  100. if muxer.OnPacket != nil {
  101. muxer.OnPacket(bsw.Bits())
  102. }
  103. bsw.Reset()
  104. pespkg := NewPesPacket()
  105. for len(frame) > 0 {
  106. peshdrlen := 13
  107. pespkg.Stream_id = sid
  108. pespkg.PTS_DTS_flags = 0x03
  109. pespkg.PES_header_data_length = 10
  110. pespkg.Pts = pts
  111. pespkg.Dts = dts
  112. if idr_flag {
  113. pespkg.Data_alignment_indicator = 1
  114. }
  115. if first && !withaud && vcl {
  116. if stream.Stream_type == uint8(PS_STREAM_H264) {
  117. pespkg.Pes_payload = append(pespkg.Pes_payload, H264_AUD_NALU...)
  118. peshdrlen += 6
  119. } else if stream.Stream_type == uint8(PS_STREAM_H265) {
  120. pespkg.Pes_payload = append(pespkg.Pes_payload, H265_AUD_NALU...)
  121. peshdrlen += 7
  122. }
  123. }
  124. if peshdrlen+len(frame) >= 0xFFFF {
  125. pespkg.PES_packet_length = 0xFFFF
  126. pespkg.Pes_payload = append(pespkg.Pes_payload, frame[0:0xFFFF-peshdrlen]...)
  127. frame = frame[0xFFFF-peshdrlen:]
  128. } else {
  129. pespkg.PES_packet_length = uint16(peshdrlen + len(frame))
  130. pespkg.Pes_payload = append(pespkg.Pes_payload, frame[0:]...)
  131. frame = frame[:0]
  132. }
  133. pespkg.Encode(bsw)
  134. pespkg.Pes_payload = pespkg.Pes_payload[:0]
  135. if muxer.OnPacket != nil {
  136. muxer.OnPacket(bsw.Bits())
  137. }
  138. bsw.Reset()
  139. first = false
  140. }
  141. return nil
  142. }