mirror of https://bitbucket.org/ausocean/av.git
Created testing file. Everything seems to be working at this point, but I'll need to test with video
This commit is contained in:
parent
b25765d59b
commit
037e7a4154
|
@ -72,8 +72,7 @@ func boolToByte( in bool ) (out uint8){
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// bool to int, shift accordigly, int to string, string binary to int
|
func (p *MpegTsPacket) ToByteSlice() (output [188]byte) {
|
||||||
func (p *MpegTsPacket) toByteSlice() (output [188]byte) {
|
|
||||||
output[0] = p.SyncByte
|
output[0] = p.SyncByte
|
||||||
output[1] = ( boolToByte(p.TEI) << (8-teiIndex%8) ) |
|
output[1] = ( boolToByte(p.TEI) << (8-teiIndex%8) ) |
|
||||||
( boolToByte(p.PUSI) << (8-pusiIndex%8) ) |
|
( boolToByte(p.PUSI) << (8-pusiIndex%8) ) |
|
||||||
|
@ -81,12 +80,12 @@ func (p *MpegTsPacket) toByteSlice() (output [188]byte) {
|
||||||
byte(( p.PID & 0xFF00 ) >> 8)
|
byte(( p.PID & 0xFF00 ) >> 8)
|
||||||
output[2] = byte(p.PID & 0x00FF)
|
output[2] = byte(p.PID & 0x00FF)
|
||||||
output[3] = ( p.TSC << 6 ) | ( p.AFC << 4 ) | p.CC
|
output[3] = ( p.TSC << 6 ) | ( p.AFC << 4 ) | p.CC
|
||||||
afLen := len(p.AF)
|
for ii := 4; ii-4 < len(p.AF); ii++ {
|
||||||
for ii := 4; ii-4 < afLen; ii++ {
|
|
||||||
output[ii] = p.AF[ii-4]
|
output[ii] = p.AF[ii-4]
|
||||||
}
|
}
|
||||||
for ii := afLen; ii < packetLength; ii++ {
|
headerSize := packetLength-len(p.Payload)
|
||||||
output[ii] = p.Payload[ii-afLen]
|
for ii := headerSize; ii < packetLength; ii++ {
|
||||||
|
output[ii] = p.Payload[ii-headerSize]
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ type Session struct {
|
||||||
rtcpChan chan<- []byte
|
rtcpChan chan<- []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(rtp, rtcp net.PacketConn) *Session {
|
func NewSession(rtp, rtcp net.PacketConn) *Session {
|
||||||
rtpChan := make(chan RtpPacket, 10)
|
rtpChan := make(chan RtpPacket, 10)
|
||||||
rtcpChan := make(chan []byte, 10)
|
rtcpChan := make(chan []byte, 10)
|
||||||
s := &Session{
|
s := &Session{
|
||||||
|
|
|
@ -28,8 +28,6 @@ LICENSE
|
||||||
|
|
||||||
package packet
|
package packet
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
type RtpToTsConverter interface {
|
type RtpToTsConverter interface {
|
||||||
Convert()
|
Convert()
|
||||||
}
|
}
|
||||||
|
@ -46,15 +44,15 @@ type rtpToTsConverter struct {
|
||||||
|
|
||||||
func NewRtpToTsConverter() (c *rtpToTsConverter) {
|
func NewRtpToTsConverter() (c *rtpToTsConverter) {
|
||||||
c = new(rtpToTsConverter)
|
c = new(rtpToTsConverter)
|
||||||
tsChan := make(chan *MpegTsPacket)
|
tsChan := make(chan *MpegTsPacket,100)
|
||||||
rtpChan := make(chan RtpPacket)
|
rtpChan := make(chan RtpPacket,100)
|
||||||
c.TsChan = tsChan
|
c.TsChan = tsChan
|
||||||
c.RtpChan = rtpChan
|
c.RtpChan = rtpChan
|
||||||
c.tsChan = tsChan
|
c.tsChan = tsChan
|
||||||
c.rtpChan = rtpChan
|
c.rtpChan = rtpChan
|
||||||
c.currentTsPacket = new(MpegTsPacket)
|
c.currentTsPacket = new(MpegTsPacket)
|
||||||
c.currentCC = 0
|
c.currentCC = 0
|
||||||
c.payloadByteChan = make(chan byte, 100)
|
c.payloadByteChan = make(chan byte, 10000)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,14 +61,10 @@ func (c* rtpToTsConverter) Convert() {
|
||||||
select{
|
select{
|
||||||
default:
|
default:
|
||||||
case rtpPacket := <-c.rtpChan:
|
case rtpPacket := <-c.rtpChan:
|
||||||
fmt.Println("here4")
|
|
||||||
for ii := range rtpPacket.Payload {
|
for ii := range rtpPacket.Payload {
|
||||||
c.payloadByteChan<-rtpPacket.Payload[ii]
|
c.payloadByteChan<-rtpPacket.Payload[ii]
|
||||||
}
|
}
|
||||||
// If we have 156 bytes of payload then we can fill up a mpegts packet
|
for len(c.payloadByteChan) > 156 {
|
||||||
fmt.Println("here5")
|
|
||||||
if len(c.payloadByteChan) > 156 {
|
|
||||||
fmt.Println("here6")
|
|
||||||
c.currentTsPacket = new(MpegTsPacket)
|
c.currentTsPacket = new(MpegTsPacket)
|
||||||
c.currentTsPacket.SyncByte = 0x47
|
c.currentTsPacket.SyncByte = 0x47
|
||||||
c.currentTsPacket.TEI = false
|
c.currentTsPacket.TEI = false
|
||||||
|
@ -78,11 +72,9 @@ func (c* rtpToTsConverter) Convert() {
|
||||||
c.currentTsPacket.Priority = false
|
c.currentTsPacket.Priority = false
|
||||||
c.currentTsPacket.PID = 4096
|
c.currentTsPacket.PID = 4096
|
||||||
c.currentTsPacket.TSC = 0
|
c.currentTsPacket.TSC = 0
|
||||||
c.currentTsPacket.AFC = 1 // no adaptation field - payload only
|
c.currentTsPacket.AFC = 1
|
||||||
c.currentTsPacket.Payload = make([]byte, 156)
|
c.currentTsPacket.Payload = make([]byte, 156)
|
||||||
fmt.Println("here7")
|
|
||||||
for ii:=0; ii < 156; ii++ {
|
for ii:=0; ii < 156; ii++ {
|
||||||
fmt.Println("here8")
|
|
||||||
c.currentTsPacket.Payload[ii] = <-c.payloadByteChan
|
c.currentTsPacket.Payload[ii] = <-c.payloadByteChan
|
||||||
}
|
}
|
||||||
c.tsChan<-c.currentTsPacket
|
c.tsChan<-c.currentTsPacket
|
||||||
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
package packet
|
||||||
|
|
||||||
|
import (
|
||||||
|
//"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/beatgammit/rtsp"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
rtpPort = 17300
|
||||||
|
rtcpPort = 17319
|
||||||
|
rtspUrl = "rtsp://192.168.0.50:8554/CH002.sdp"
|
||||||
|
rtpUrl = "rtsp://192.168.0.50:8554/CH002.sdp/track1"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* Let's see if we can connect to an rtsp device then read an rtp stream,
|
||||||
|
and then convert the rtp packets to mpegts packets and output. */
|
||||||
|
func TestMain(t *testing.T) {
|
||||||
|
sess := rtsp.NewSession()
|
||||||
|
res, err := sess.Options(rtspUrl)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Shouldn't have got error: %v\n",err)
|
||||||
|
}
|
||||||
|
fmt.Println("Options:")
|
||||||
|
fmt.Println(res)
|
||||||
|
|
||||||
|
res, err = sess.Describe(rtspUrl)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
t.Errorf("Shouldn't have got error: %v\n", err)
|
||||||
|
}
|
||||||
|
fmt.Println("Describe:")
|
||||||
|
fmt.Println(res)
|
||||||
|
|
||||||
|
p, err := rtsp.ParseSdp(&io.LimitedReader{R: res.Body, N: res.ContentLength})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Shouldn't have got error: %v\n", err)
|
||||||
|
}
|
||||||
|
log.Printf("%+v", p)
|
||||||
|
|
||||||
|
fmt.Println("Setting up!")
|
||||||
|
res, err = sess.Setup(rtpUrl, fmt.Sprintf("RTP/AVP;unicast;client_port=%d-%d", rtpPort, rtcpPort))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Shouldn't have got error: %v\n", err)
|
||||||
|
}
|
||||||
|
log.Println(res)
|
||||||
|
|
||||||
|
fmt.Println("Playing !")
|
||||||
|
res, err = sess.Play(rtspUrl, res.Header.Get("Session"))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Shouldn't have got error: %v\n", err)
|
||||||
|
}
|
||||||
|
log.Println(res)
|
||||||
|
|
||||||
|
// create udp connection for rtp stuff
|
||||||
|
rtpLaddr, err := net.ResolveUDPAddr("udp", "192.168.0.109:17300")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Local rtp addr not set! %v\n",err)
|
||||||
|
}
|
||||||
|
rtpAddr, err := net.ResolveUDPAddr("udp", "192.168.0.50:17300")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Resolving rtp address didn't work! %v\n", err)
|
||||||
|
}
|
||||||
|
rtpConn, err := net.DialUDP("udp", rtpLaddr, rtpAddr)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Conncection not established! %v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create udp connection for rtcp stuff
|
||||||
|
rtcpLaddr, err := net.ResolveUDPAddr("udp", "192.168.0.109:17319")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Local RTCP address not resolved! %v\n", err)
|
||||||
|
}
|
||||||
|
rtcpAddr, err := net.ResolveUDPAddr("udp", "192.168.0.50:17301")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Remote RTCP address not resolved! %v\n", err)
|
||||||
|
}
|
||||||
|
rtcpConn, err := net.DialUDP("udp", rtcpLaddr, rtcpAddr)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Connection not established! %v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// let's create a session that will store useful stuff from the connections
|
||||||
|
rtpSession := NewSession(rtpConn, rtcpConn)
|
||||||
|
converter := NewRtpToTsConverter()
|
||||||
|
go converter.Convert()
|
||||||
|
for ii:=0;ii<10000000;ii++{
|
||||||
|
select{
|
||||||
|
default:
|
||||||
|
case rtpPacket := <-rtpSession.RtpChan:
|
||||||
|
converter.RtpChan<-rtpPacket
|
||||||
|
case tsPacket:=<-converter.TsChan:
|
||||||
|
fmt.Println(tsPacket.ToByteSlice())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -88,7 +88,7 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// let's create a session that will store useful stuff from the connections
|
// let's create a session that will store useful stuff from the connections
|
||||||
rtpSession := packet.New(rtpConn, rtcpConn)
|
rtpSession := packet.NewSession(rtpConn, rtcpConn)
|
||||||
converter := packet.NewRtpToTsConverter()
|
converter := packet.NewRtpToTsConverter()
|
||||||
go converter.Convert()
|
go converter.Convert()
|
||||||
for {
|
for {
|
||||||
|
@ -96,12 +96,9 @@ func main() {
|
||||||
default:
|
default:
|
||||||
case rtpPacket := <-rtpSession.RtpChan:
|
case rtpPacket := <-rtpSession.RtpChan:
|
||||||
converter.RtpChan<-rtpPacket
|
converter.RtpChan<-rtpPacket
|
||||||
fmt.Println("here2")
|
|
||||||
case tsPacket:=<-converter.TsChan:
|
case tsPacket:=<-converter.TsChan:
|
||||||
fmt.Println("here3")
|
fmt.Println(tsPacket.ToByteSlice())
|
||||||
fmt.Println(tsPacket)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue