/* NAME RtpToTsConverter.go - provides utilities for the conversion of Rtp packets to equivalent MpegTs packets. DESCRIPTION See Readme.md AUTHOR Saxon Nelson-Milton LICENSE RtpToTsConverter.go is Copyright (C) 2017 the Australian Ocean Lab (AusOcean) It is free software: you can redistribute it and/or modify them under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. It is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with revid in gpl.txt. If not, see [GNU licenses](http://www.gnu.org/licenses). */ package packets import "fmt" type RtpToTsConverter interface { Convert() } type rtpToTsConverter struct { TsChan <-chan *MpegTsPacket tsChan chan<- *MpegTsPacket currentTsPacket *MpegTsPacket payloadByteChan chan byte currentCC byte } func NewRtpToTsConverter() (c *rtpToTsConverter) { c = new(rtpToTsConverter) tsChan := make(chan *MpegTsPacket,100) c.TsChan = tsChan c.tsChan = tsChan c.payloadByteChan = make(chan byte, 10000) c.currentCC = 0 return } func (c* rtpToTsConverter) Convert(rtpSession *Session) { for { select{ default: case rtpPacket := <-rtpSession.RtpChan: for ii := range rtpPacket.Payload { c.payloadByteChan<-rtpPacket.Payload[ii] } for len(c.payloadByteChan) > 0 { lengthOfByteChan := len(c.payloadByteChan) c.currentTsPacket = new(MpegTsPacket) c.currentTsPacket.SyncByte = 0x47 c.currentTsPacket.TEI = false if lengthOfByteChan == len(rtpPacket.Payload) { // if it's the start of the payload c.currentTsPacket.PUSI = true } else { c.currentTsPacket.PUSI = false } c.currentTsPacket.Priority = false c.currentTsPacket.PID = 256 c.currentTsPacket.TSC = 0 c.currentTsPacket.AFC = 3 // adaptationfield followed by payload c.currentTsPacket.CC = c.currentCC if c.currentCC++; c.currentCC > 15 { c.currentCC = 0 } payloadLength := 140 if lengthOfByteChan < 140 { payloadLength = lengthOfByteChan } stuffingLength := 140-payloadLength c.currentTsPacket.AF = make([]byte,2 + stuffingLength) // adaptationfield flag length = 16 c.currentTsPacket.AF[0] = byte(1 + stuffingLength) c.currentTsPacket.AF[1] = 0 for ii := 0; ii < stuffingLength; ii++ { c.currentTsPacket.AF[2+ii] = 0xFF } c.currentTsPacket.Payload = make([]byte, payloadLength) for ii:=0; ii < payloadLength; ii++ { c.currentTsPacket.Payload[ii] = <-c.payloadByteChan } c.tsChan<-c.currentTsPacket } } } }