mirror of https://bitbucket.org/ausocean/av.git
239 lines
6.3 KiB
Go
239 lines
6.3 KiB
Go
/*
|
|
NAME
|
|
MpegTs.go - provides a data structure intended to encapsulate the properties
|
|
of an MpegTs packet.
|
|
|
|
DESCRIPTION
|
|
See Readme.md
|
|
|
|
AUTHOR
|
|
Saxon Nelson-Milton <saxon.milton@gmail.com>
|
|
|
|
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){
|
|
|
|
}
|