(rtpItem *LIRTP)
| 98 | } |
| 99 | |
| 100 | func (vt *H265) WriteRTPFrame(rtpItem *LIRTP) { |
| 101 | defer func() { |
| 102 | err := recover() |
| 103 | if err != nil { |
| 104 | vt.Error("WriteRTPFrame panic", zap.Any("err", err)) |
| 105 | vt.Publisher.Stop(zap.Any("err", err)) |
| 106 | } |
| 107 | }() |
| 108 | frame := &rtpItem.Value |
| 109 | rv := vt.Value |
| 110 | rv.RTP.Push(rtpItem) |
| 111 | // TODO: DONL may need to be parsed if `sprop-max-don-diff` is greater than 0 on the RTP stream. |
| 112 | var usingDonlField bool |
| 113 | var buffer = util.Buffer(frame.Payload) |
| 114 | switch frame.H265Type() { |
| 115 | case codec.NAL_UNIT_RTP_AP: |
| 116 | buffer.ReadUint16() |
| 117 | if usingDonlField { |
| 118 | buffer.ReadUint16() |
| 119 | } |
| 120 | for buffer.CanRead() { |
| 121 | l := int(buffer.ReadUint16()) |
| 122 | if buffer.CanReadN(l) { |
| 123 | vt.WriteSliceBytes(buffer.ReadN(l)) |
| 124 | } else { |
| 125 | return |
| 126 | } |
| 127 | if usingDonlField { |
| 128 | buffer.ReadByte() |
| 129 | } |
| 130 | } |
| 131 | case codec.NAL_UNIT_RTP_FU: |
| 132 | if !buffer.CanReadN(3) { |
| 133 | return |
| 134 | } |
| 135 | first3 := buffer.ReadN(3) |
| 136 | fuHeader := first3[2] |
| 137 | if usingDonlField { |
| 138 | buffer.ReadUint16() |
| 139 | } |
| 140 | if naluType := fuHeader & 0b00111111; util.Bit1(fuHeader, 0) { |
| 141 | vt.WriteSliceByte(first3[0]&0b10000001|(naluType<<1), first3[1]) |
| 142 | } |
| 143 | if rv.AUList.Pre != nil { |
| 144 | rv.AUList.Pre.Value.Push(vt.BytesPool.GetShell(buffer)) |
| 145 | } |
| 146 | default: |
| 147 | vt.WriteSliceBytes(frame.Payload) |
| 148 | } |
| 149 | if frame.Marker { |
| 150 | vt.generateTimestamp(frame.Timestamp) |
| 151 | if !vt.dcChanged && rv.IFrame { |
| 152 | vt.insertDCRtp() |
| 153 | } |
| 154 | vt.Flush() |
| 155 | } |
| 156 | } |
| 157 |
nothing calls this directly
no test coverage detected