From 76df33ceb9e5654ccf183a06ebf468105cd34b8e Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 13 Mar 2018 15:03:31 +1030 Subject: [PATCH] Fixing bugs --- flv/FLV.go | 2 +- generator/FLVGenerator.go | 24 ++--- generator/MPEGTSGenerator.go | 43 ++++----- mpegts/MpegTs.go | 12 +-- parser/H264Writer.go | 153 ------------------------------- revid/RevidInstance.go | 3 +- revid/revid_test.go | 6 +- rtp/Rtp.go | 160 --------------------------------- rtp/camstreamer.go | 169 ----------------------------------- tools/helpers.go | 13 --- 10 files changed, 48 insertions(+), 537 deletions(-) delete mode 100644 parser/H264Writer.go delete mode 100644 rtp/Rtp.go delete mode 100644 rtp/camstreamer.go diff --git a/flv/FLV.go b/flv/FLV.go index b7192c02..14045ed2 100644 --- a/flv/FLV.go +++ b/flv/FLV.go @@ -66,7 +66,7 @@ func btb(b bool) byte { func (h *Header) ToByteSlice() (output []byte) { output = make([]byte, 0, headerLength) - output = append(output, flvheaderCode...) + output = append(output, flvHeaderCode...) output = append(output, []byte { version, 0x00 | btb(h.AudioFlag)<<2 | btb(h.VideoFlag), diff --git a/generator/FLVGenerator.go b/generator/FLVGenerator.go index 21c34139..eda24c4a 100644 --- a/generator/FLVGenerator.go +++ b/generator/FLVGenerator.go @@ -131,16 +131,17 @@ func getNalType(frame []byte) byte { } } } + return 0x00 } // isKeyFrame checks the nature of the passed frame - returning true if the // frame is keyframe and false otherwise func isKeyFrame(frame []byte) bool { - nalType := getNaleType(frame) + nalType := getNalType(frame) switch { case nalType == interFrameCode: return false - case nalType == keyFramecode || nalType == 6: + case nalType == keyFrameCode || nalType == 6: return true } return false @@ -149,9 +150,9 @@ func isKeyFrame(frame []byte) bool { // isSequenceHeader checks the nature of the passed frame and returns true // if it is a sequnce header and false otherwise func isSequenceHeader(frame []byte) bool { - nalType := getnaleType(frame) + nalType := getNalType(frame) switch { - case nalType == 1 || naltype == 5: + case nalType == 1 || nalType == 5: return false case nalType == 6 || nalType == 7 || nalType == 8: return true @@ -181,7 +182,7 @@ func (g *flvGenerator) generate() { timeStamp := g.getNextTimestamp() // Do we have video to send off ? if g.videoFlag { - g.outputChan <- flv.VideoTag{ + tag := flv.VideoTag{ TagType: uint8(flv.VideoTagType), DataSize: uint32(len(videoFrame)) + flv.DataHeaderLength, Timestamp: timeStamp, @@ -192,12 +193,13 @@ func (g *flvGenerator) generate() { CompositionTime: 0, Data: videoFrame, PrevTagSize: uint32(videoHeaderSize + len(videoFrame)), - }.ToByteSlice() + } + g.outputChan <- tag.ToByteSlice() } // Do we even have some audio to send off ? if g.audioFlag { // Not sure why but we need two audio tags for dummy silent audio - g.outputChan <- flv.AudioTag{ + tag := flv.AudioTag{ TagType: uint8(flv.AudioTagType), DataSize: 7, Timestamp: timeStamp, @@ -208,9 +210,10 @@ func (g *flvGenerator) generate() { SoundType: true, Data: dummyAudioTag1Data, PrevTagSize: uint32(audioSize), - }.ToByteSlice() + } + g.outputChan <- tag.ToByteSlice() - g.outputChan <- flv.AudioTag{ + tag = flv.AudioTag{ TagType: uint8(flv.AudioTagType), DataSize: 21, Timestamp: timeStamp, @@ -221,7 +224,8 @@ func (g *flvGenerator) generate() { SoundType: true, Data: dummyAudioTag2Data, PrevTagSize: uint32(22), - }.ToByteSlice() + } + g.outputChan <- tag.ToByteSlice() } } } diff --git a/generator/MPEGTSGenerator.go b/generator/MPEGTSGenerator.go index 46c1aca4..2fbbf6fc 100644 --- a/generator/MPEGTSGenerator.go +++ b/generator/MPEGTSGenerator.go @@ -35,8 +35,8 @@ import ( //"bitbucket.org/ausocean/av/rtp" "../mpegts" "../pes" - "../rtp" - "../tools" + //"../rtp" + //"../tools" ) // TODO: really need to finish the at and pmt stuff - this is too hacky @@ -44,7 +44,7 @@ var ( patTableStart = []byte{0, 0, 176, 13, 0, 1, 193, 0, 0, 0, 1, 240, 0, 42, 177, 4, 178} patTable []byte pmtTableStart = []byte{0, 2, 176, 18, 0, 1, 193, 0, 0, 0xE1, 0x00, 0xF0, 0, 0x1B, 0xE1, 0, 0xF0, 0, 0x15, 0xBD, 0x4D, 0x56} - pmtTble []byte + pmtTable []byte ) // genPatAndPmt generates the rest of the pat and pmt tables i.e. fills them @@ -52,14 +52,14 @@ var ( // NewMpegtsgenerator func genPatAndPmt() { patTable = make([]byte, 0, 184) - patTable = append(pat, patTableStart...) + patTable = append(patTable, patTableStart...) for i := 0; i < 167; i++ { - pmtTable = append(pmt, 255) + pmtTable = append(pmtTable, 255) } pmtTable = make([]byte, 0, 184) - pmtTable = append(pmt, pmtTableStart...) + pmtTable = append(pmtTable, pmtTableStart...) for i := 0; i < 162; i++ { - pmtTable = append(pmt, 255) + pmtTable = append(pmtTable, 255) } } @@ -70,16 +70,15 @@ const ( videoPid = 256 streamID = 0xE0 outputChanSize = 100 - inputChanSie = 10000 + inputChanSize = 10000 pesPktChanSize = 1000 - payloadbyteChanSize = 100000 + payloadByteChanSize = 100000 ptsOffset = .7 maxCC = 15 ) // tsGenerator encapsulates properties of an mpegts generator. type tsGenerator struct { - rtpInputChan chan rtp.RtpPacket outputChan chan []byte nalInputChan chan []byte currentTsPacket *mpegts.MpegTsPacket @@ -113,14 +112,14 @@ func NewTsGenerator(fps uint) (g *tsGenerator) { g.fps = fps g.currentPcrTime = 0.0 g.currentPtsTime = ptsOffset - g.pesPktChan = make(chan []byte, pesPktchanSize) + g.pesPktChan = make(chan []byte, pesPktChanSize) g.payloadByteChan = make(chan byte, payloadByteChanSize) g.ccMap = make(map[int]int, 4) g.ccMap[SdtPid] = 0 g.ccMap[PatPid] = 0 g.ccMap[pmtPid] = 0 g.ccMap[videoPid] = 0 - getPatAndPmt() + genPatAndPmt() return } @@ -144,7 +143,7 @@ func (g *tsGenerator) Start() { go g.generate() } -// getCC returns the next continuity counter for a particular pid +// getCC returns the next continuity counter for a particular pid func (g *tsGenerator) getCC(pid int) int { temp := g.ccMap[pid] if g.ccMap[pid]++; g.ccMap[pid] > maxCC { @@ -156,17 +155,17 @@ func (g *tsGenerator) getCC(pid int) int { // generate handles the incoming data and generates equivalent mpegts packets - // sending them to the output channel func (g *tsGenerator) generate() { - var rtpBuffer [](*rtp.RtpPacket) for { select { case nalUnit := <-g.nalInputChan: - g.pesPktChan <- pes.PESPacket{ + pesPkt := pes.PESPacket{ StreamID: streamID, PDI: byte(2), PTS: g.genPts(), Data: nalUnit, HeaderLength: 5, - }.ToByteSlice() + } + g.pesPktChan <- pesPkt.ToByteSlice() case pesPkt := <-g.pesPktChan: for ii := range pesPkt { g.payloadByteChan <- pesPkt[ii] @@ -185,21 +184,23 @@ func (g *tsGenerator) generate() { if pusi { // Create pat table - g.outputChan <- mpegts.MpegTsPacket{ + patPkt := mpegts.MpegTsPacket{ PUSI: pusi, PID: PatPid, CC: byte(g.getCC(PatPid)), AFC: 1, - Payload: PatTable, - }.ToByteSlise() + Payload: patTable, + } + g.outputChan <- patPkt.ToByteSlice() // Create pmt table - g.outputChan <- mpegts.MpegTsPacket{ + pmtPkt := mpegts.MpegTsPacket{ PUSI: pusi, PID: pmtPid, CC: byte(g.getCC(pmtPid)), AFC: 1, Payload: pmtTable, - }.ToByteSlise() + } + g.outputChan <- pmtPkt.ToByteSlice() // If pusi then we need to gen a pcr pkt.PCR = g.genPcr() pusi = false diff --git a/mpegts/MpegTs.go b/mpegts/MpegTs.go index ee6615ec..491a9080 100644 --- a/mpegts/MpegTs.go +++ b/mpegts/MpegTs.go @@ -32,7 +32,7 @@ import ( //"bitbucket.org/ausocean/av/tools" "../tools" - "errors" + _"errors" //"fmt" ) @@ -128,18 +128,18 @@ type MpegTsPacket struct { TPDL byte // Tranposrt private data length TPD []byte // Private data Ext []byte // Adaptation field extension - payload []byte // Mpeg ts payload + Payload []byte // Mpeg ts Payload } -// FillPayload takes a channel and fills the packets payload field until the +// FillPayload takes a channel and fills the packets Payload field until the // channel is empty or we've the packet reaches capacity func (p *MpegTsPacket) FillPayload(channel chan byte){ p.Payload = make([]byte,0,mpegtsPayloadSize) currentPktLength := 6 + int(btb(p.PCRF))*6+int(btb(p.OPCRF))*6+ int(btb(p.SPF))*1+int(btb(p.TPDF))*1+len(p.TPD) // While we're within the mpegts packet size and we still have data we can use - for (currentPktLength+len(p.Payload)) < mpegTsSize && len(cannel) > 0 { - p.payload = append(p.payload,<-channel) + for (currentPktLength+len(p.Payload)) < mpegTsSize && len(channel) > 0 { + p.Payload = append(p.Payload,<-channel) } } @@ -150,7 +150,7 @@ func btb(b bool) byte { } // ToByteSlice interprets the fields of the ts packet instance and outputs a -// corresponding byte slice +// corresponding byte slice func (p *MpegTsPacket) ToByteSlice() (output []byte) { stuffingLength := 182-len(p.Payload)-len(p.TPD)-int(btb(p.PCRF))*6- int(btb(p.OPCRF))*6 - int(btb(p.SPF)) diff --git a/parser/H264Writer.go b/parser/H264Writer.go deleted file mode 100644 index 334dbe28..00000000 --- a/parser/H264Writer.go +++ /dev/null @@ -1,153 +0,0 @@ -/* -NOTE: this file is in progress... - -NAME - H264Writer.go - -DESCRIPTION - See Readme.md - -AUTHOR - Saxon Nelson-Milton - -LICENSE - H264Writer.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). -*/ - -// TODO: complete this file - -package parser - -import ( - _"fmt" - "os" - - //"bitbucket.org/ausocean/av/mpegts" - //"bitbucket.org/ausocean/av/rtp" - //"bitbucket.org/ausocean/av/tools" - //"bitbucket.org/ausocean/av/itut" - "../mpegts" - "../rtp" - "../tools" - "../itut" -) - -type RtpToH264Converter interface { - Convert() -} - -type rtpToH264Converter struct { - TsChan <-chan *mpegts.MpegTsPacket - tsChan chan<- *mpegts.MpegTsPacket - InputChan chan<- rtp.RtpPacket - inputChan <-chan rtp.RtpPacket - currentTsPacket *mpegts.MpegTsPacket - payloadByteChan chan byte - currentCC byte -} - -//func parseH264File() -func NewRtpToH264Converter() (c *rtpToH264Converter) { - c = new(rtpToH264Converter) - tsChan := make(chan *mpegts.MpegTsPacket,100) - c.TsChan = tsChan - c.tsChan = tsChan - inputChan := make(chan rtp.RtpPacket,100) - c.InputChan = inputChan - c.inputChan = inputChan - c.currentCC = 0 - return -} - -func (c* rtpToH264Converter) Convert() { - file,_ := os.Create("video") - var rtpBuffer [](*rtp.RtpPacket) - for { - select { - default: - case rtpPacket := <-c.inputChan: - rtpBuffer = append(rtpBuffer,&rtpPacket) - if len(rtpBuffer) > 2 { - // if there's something weird going on with sequence numbers then sort - if rtpPacket.SequenceNumber < rtpBuffer[len(rtpBuffer)-2].SequenceNumber { - for i := 1; i < len(rtpBuffer); i++ { - for j := i; j > 0 && rtpBuffer[j].SequenceNumber < rtpBuffer[j - 1].SequenceNumber; j-- { - temp := rtpBuffer[j] - rtpBuffer[j] = rtpBuffer[j-1] - rtpBuffer[j-1] = temp - } - } - } - } - if len(rtpBuffer) > 200 { - // Discard everything before a type 7 - for tools.GetOctectType(rtpBuffer[0]) != 7 { - rtpBuffer = rtpBuffer[1:] - } - // get sps - sps := make([]byte,len(rtpBuffer[0].Payload)) - copy(sps[:],rtpBuffer[0].Payload[:]) - rtpBuffer = rtpBuffer[1:] - // get pps - pps := make([]byte,len(rtpBuffer[0].Payload)) - copy(pps[:],rtpBuffer[0].Payload[:]) - rtpBuffer = rtpBuffer[1:] - // get sei - sei := make([]byte, len(rtpBuffer[0].Payload)) - copy(sei[:],rtpBuffer[0].Payload[:]) - rtpBuffer = rtpBuffer[1:] - // while we haven't reached the next sps in the buffer - for tools.GetOctectType(rtpBuffer[0]) != 7 { - switch(tools.GetOctectType(rtpBuffer[0])){ - case 28: - if tools.GetStartBit(rtpBuffer[0]) == 1{ - var buffer []byte - buffer = append(buffer, append(itut.StartCode1(),itut.AUD()...)...) - buffer = append(buffer, append(itut.StartCode1(),sps...)...) - buffer = append(buffer, append(itut.StartCode1(),pps...)...) - buffer = append(buffer, append(itut.StartCode1(),sei...)...) - buffer = append(buffer, itut.StartCode1()...) - buffer = append(buffer, rtpBuffer[0].Payload[0] & 0xE0 | rtpBuffer[0].Payload[1] & 0x1F ) - buffer = append(buffer, rtpBuffer[0].Payload[2:]...) - rtpBuffer = rtpBuffer[1:] - for { - buffer = append(buffer, rtpBuffer[0].Payload[2:]...) - if tools.GetEndBit(rtpBuffer[0]) == 1 { - rtpBuffer = rtpBuffer[1:] - file.Write(buffer) - break - } - rtpBuffer = rtpBuffer[1:] - } - } - case 1: - var buffer []byte - buffer = append(buffer, append(itut.StartCode1(), itut.AUD()...)...) - buffer = append(buffer, append(itut.StartCode1(), sps...)...) - buffer = append(buffer, append(itut.StartCode1(),pps...)...) - buffer = append(buffer, append(itut.StartCode1(),sei...)...) - buffer = append(buffer, itut.StartCode1()...) - buffer = append(buffer, rtpBuffer[0].Payload[0] & 0xE0 | rtpBuffer[0].Payload[1] & 0x1F ) - buffer = append(buffer, rtpBuffer[0].Payload[2:]...) - rtpBuffer = rtpBuffer[1:] - file.Write(buffer) - default: - } - } - } - } - } -} diff --git a/revid/RevidInstance.go b/revid/RevidInstance.go index 0e8e5d98..d67c242a 100644 --- a/revid/RevidInstance.go +++ b/revid/RevidInstance.go @@ -109,7 +109,6 @@ type revidInst struct { setupInput func() error setupOutput func() error getFrame func() []byte - flushData func() sendClip func(clip []byte) error rtmpInst rtmp.RTMPSession } @@ -124,7 +123,7 @@ func NewRevidInstance(config Config) (r *revidInst, err error) { if err != nil { return nil, err } - r.outputChan = make(chan []byte, outputchanSize) + r.outputChan = make(chan []byte, outputChanSize) r.parser.Start() go r.packClips() r.Log(Info, "New revid instance created! config is:") diff --git a/revid/revid_test.go b/revid/revid_test.go index d4f3f8ae..3610b52e 100644 --- a/revid/revid_test.go +++ b/revid/revid_test.go @@ -142,7 +142,7 @@ func TestFlvOutputFile(t *testing.T) { time.Sleep(30 * time.Second) revidInst.Stop() } - +*/ // Test h264 inputfile to flv format into rtmp using librtmp c wrapper func TestRtmpOutputUsingLibRtmp(t *testing.T){ @@ -166,8 +166,9 @@ func TestRtmpOutputUsingLibRtmp(t *testing.T){ time.Sleep(120*time.Second) revidInst.Stop() } -*/ + +/* // Test revidInst with a Raspivid h264 input func TestRaspividToRtmp(t *testing.T){ config := Config{ @@ -188,3 +189,4 @@ func TestRaspividToRtmp(t *testing.T){ time.Sleep(120*time.Second) revidInst.Stop() } +*/ diff --git a/rtp/Rtp.go b/rtp/Rtp.go deleted file mode 100644 index 78ea67e1..00000000 --- a/rtp/Rtp.go +++ /dev/null @@ -1,160 +0,0 @@ -/* -Copyright (c) 2015, T. Jameson Little -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this -list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, -this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors -may be used to endorse or promote products derived from this software without -specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package rtp - -import ( - "net" - _"fmt" -) - -const ( - RTP_VERSION = 2 -) - -const ( - hasRtpPadding = 1 << 5 - hasRtpExt = 1 << 4 - hasMarker = 1 << 7 -) - -type RtpPacket struct { - Version byte - Padding bool - Ext bool - CC byte - Marker bool - PayloadType byte - SequenceNumber uint - Timestamp uint - SyncSource uint - CSRC []uint - ExtHeader uint - ExtData []byte - Payload []byte -} - -type Session struct { - Rtp net.PacketConn - Rtcp net.PacketConn - RtpChan <-chan RtpPacket - RtcpChan <-chan []byte - rtpChan chan<- RtpPacket - rtcpChan chan<- []byte -} - -func NewSession(rtp, rtcp net.PacketConn) *Session { - rtpChan := make(chan RtpPacket, 10) - rtcpChan := make(chan []byte, 10) - s := &Session{ - Rtp: rtp, - Rtcp: rtcp, - RtpChan: rtpChan, - RtcpChan: rtcpChan, - rtpChan: rtpChan, - rtcpChan: rtcpChan, - } - go s.HandleRtpConn(rtp) - go s.HandleRtcpConn(rtcp) - return s -} - -func toUint(arr []byte) (ret uint) { - for i, b := range arr { - ret |= uint(b) << (8 * uint(len(arr)-i-1)) - } - return ret -} - -func (s *Session) HandleRtpConn(conn net.PacketConn) { - buf := make([]byte, 4096) - for { - n, _, err := conn.ReadFrom(buf) - if err != nil { - panic(err) - } - cpy := make([]byte, n) - copy(cpy, buf) - go s.handleRtp(cpy) - } -} - -func (s *Session) HandleRtcpConn(conn net.PacketConn) { - buf := make([]byte, 4096) - for { - n, _, err := conn.ReadFrom(buf) - if err != nil { - panic(err) - } - cpy := make([]byte, n) - copy(cpy, buf) - go s.handleRtcp(cpy) - } -} - -func (s *Session) handleRtp(buf []byte) { - packet := RtpPacket{ - Version: (buf[0] & 0xC0) >> 6, - Padding: buf[0]&hasRtpPadding != 0, - Ext: buf[0]&hasRtpExt != 0, - CC: buf[0] & 0x0F, - Marker: buf[1]&hasMarker != 0, - PayloadType: buf[1] & 0x7F, - SequenceNumber: toUint(buf[2:4]), - Timestamp: toUint(buf[4:8]), - SyncSource: toUint(buf[8:12]), - CSRC: make([]uint, buf[0]&0x0F), - } - if packet.Version != RTP_VERSION { - panic("Unsupported version") - } - i := 12 - for j := range packet.CSRC { - packet.CSRC[j] = toUint(buf[i : i+4]) - i += 4 - } - if packet.Ext { - packet.ExtHeader = toUint(buf[i : i+2]) - length := toUint(buf[i+2 : i+4]) - i += 4 - if length > 0 { - packet.ExtData = buf[i : i+int(length)*4] - i += int(length) * 4 - } - } - packet.Payload = buf[i:] - - s.rtpChan <- packet -} - -func (s *Session) handleRtcp(buf []byte) { - // TODO: implement rtcp -} diff --git a/rtp/camstreamer.go b/rtp/camstreamer.go deleted file mode 100644 index 8a5fda82..00000000 --- a/rtp/camstreamer.go +++ /dev/null @@ -1,169 +0,0 @@ -package camstreamer - -import ( - "errors" -) - -type CamStreamer struct { - RtspUrl string - RtpUrl string - RtpPort uint16 - RtcpPort uint16 -} - -func (cs *CamStreamer)Connect()(session *RtpSession, err error){ - var res string - sess := rtsp.NewSession() - - if res, err = sess.Options(sc.RtspUrl); err != nil { - return - } - res, err = sess.Describe(rtspUrl) - if err != nil { - log.Fatalln(err) - } - p, err := rtsp.ParseSdp(&io.LimitedReader{R: res.Body, N: res.ContentLength}) - if err != nil { - } - log.Printf("%+v", p) - res, err = sess.Setup(rtpUrl, fmt.Sprintf("RTP/AVP;unicast;client_port=%d-%d", rtpPort, rtcpPort)) - if err != nil { - } - log.Println(res) - res, err = sess.Play(rtspUrl, res.Header.Get("Session")) - if err != nil { - } - 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) -} - -/******************************************************* -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) - } - - res, err = sess.Describe(rtspUrl) - if err != nil { - log.Fatalln(err) - t.Errorf("Shouldn't have got error: %v\n", err) - } - 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) - 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) - 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) - } - res, err = sess.Describe(rtspUrl) - if err != nil { - log.Fatalln(err) - t.Errorf("Shouldn't have got error: %v\n", err) - } - 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) - 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) - 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) - } -} diff --git a/tools/helpers.go b/tools/helpers.go index 638de03e..7b9edf06 100644 --- a/tools/helpers.go +++ b/tools/helpers.go @@ -32,7 +32,6 @@ import ( _"os" _"fmt" //"bitbucket.org/ausocean/av/rtp" - "../rtp" ) func BoolToByte(in bool) (out byte) { @@ -41,15 +40,3 @@ func BoolToByte(in bool) (out byte) { } return } - -func GetOctectType(p *rtp.RtpPacket) byte { - return p.Payload[0] & 0x1F -} - -func GetStartBit(p *rtp.RtpPacket) byte { - return (p.Payload[1] & 0x80) >> 7 -} - -func GetEndBit(p *rtp.RtpPacket) byte { - return (p.Payload[1] & 0x40) >> 6 -}