/* NAME MpegTs.go - provides a data structure intended to encapsulate the properties of an MpegTs packet. DESCRIPTION See Readme.md AUTHOR Saxon Nelson-Milton LICENSE MpegTs.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 ( //"bytes" "fmt" "io" "log" "net" "testing" "reflect" "time" "github.com/beatgammit/rtsp" ) /******************************************************* Testing stuff related to connection i.e. rtsp, rtp, rtcp ********************************************************/ 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 TestRTSP(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) } func TestRTP(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) time.Sleep(2*time.Second) select{ default: t.Errorf("Should have got rtpPacket!") case rtpPacket := <-rtpSession.RtpChan: fmt.Printf("RTP packet: %v\n",rtpPacket) } } /******************************************************* Testing stuff related to the Nal.go file ********************************************************/ var parseInput = []byte{ 0x6C, // 3NalUnitBits = 101(5), Fragment type = 1100 (type = 12 ) 0x94, // starbit = 1, endbit = 0, Reservedbit = 0, 5NalUnitBits = 10100 (20) 0x8E, // 10001110 random frame byte 0x26, // 00100110 random frame byte 0xD0, // 11010000 random frame byte } var expectedParsing = []interface{}{ byte(3), byte(12), bool(true), bool(false), bool(false), byte(20), []byte{0x8E,0x26,0xD0}, } const ( nalTestType = 12 ) func TestNalFragmentParsing(t *testing.T) { nalUnit := ParseNALFragment(parseInput) value := reflect.ValueOf(*nalUnit) length := value.NumField() fields := make([]interface{}, length) for ii := 0; ii < length; ii++ { fields[ii] = value.Field(ii).Interface() } for ii := range fields { if !reflect.DeepEqual(fields[ii],expectedParsing[ii]) { t.Errorf("Bad Parsing! Field: %v wanted: %v got: %v\n",ii,expectedParsing[ii],fields[ii]) } } } func TestNalFragmentToByteSlice(t *testing.T) { nalUnit := ParseNALFragment(parseInput) output := nalUnit.ToByteSlice() for ii := range output { if output[ii] != parseInput[ii] { t.Errorf("Bad conversion to byte slice at %vth byte! wanted: %v got: %v", parseInput[ii],output[ii]) } } } func TestNalFragmentType(t *testing.T){ nalUnit := ParseNALFragment(parseInput) nalType := nalUnit.GetType() if nalType != nalTestType { t.Errorf("Returned wrong type!") } } func TestNalSpsPpsParsing(t *testing.T){ NalSps := ParseNALSpsPps(parseInput) } func TestNalSpsPpsToByteSlice(t *testing.T){ } func TestNalSpsPpsType(t *testing.T){ }