first commit

This commit is contained in:
Andrey Semochkin
2019-11-30 21:53:21 +01:00
commit 087a2b4c2d
60 changed files with 19091 additions and 0 deletions

1241
format/rtsp/client.go Normal file

File diff suppressed because it is too large Load Diff

25
format/rtsp/conn.go Normal file
View File

@@ -0,0 +1,25 @@
package rtsp
import (
"net"
"time"
)
type connWithTimeout struct {
Timeout time.Duration
net.Conn
}
func (self connWithTimeout) Read(p []byte) (n int, err error) {
if self.Timeout > 0 {
self.Conn.SetReadDeadline(time.Now().Add(self.Timeout))
}
return self.Conn.Read(p)
}
func (self connWithTimeout) Write(p []byte) (n int, err error) {
if self.Timeout > 0 {
self.Conn.SetWriteDeadline(time.Now().Add(self.Timeout))
}
return self.Conn.Write(p)
}

117
format/rtsp/sdp/parser.go Normal file
View File

@@ -0,0 +1,117 @@
package sdp
import (
"encoding/base64"
"encoding/hex"
"fmt"
"strconv"
"strings"
"github.com/deepch/vdk/av"
)
type Session struct {
Uri string
}
type Media struct {
AVType string
Type av.CodecType
TimeScale int
Control string
Rtpmap int
Config []byte
SpropParameterSets [][]byte
PayloadType int
SizeLength int
IndexLength int
}
func Parse(content string) (sess Session, medias []Media) {
var media *Media
for _, line := range strings.Split(content, "\n") {
line = strings.TrimSpace(line)
typeval := strings.SplitN(line, "=", 2)
if len(typeval) == 2 {
fields := strings.SplitN(typeval[1], " ", 2)
switch typeval[0] {
case "m":
if len(fields) > 0 {
switch fields[0] {
case "audio", "video":
medias = append(medias, Media{AVType: fields[0]})
media = &medias[len(medias)-1]
mfields := strings.Split(fields[1], " ")
if len(mfields) >= 3 {
media.PayloadType, _ = strconv.Atoi(mfields[2])
}
}
}
case "u":
sess.Uri = typeval[1]
case "a":
if media != nil {
for _, field := range fields {
keyval := strings.SplitN(field, ":", 2)
if len(keyval) >= 2 {
key := keyval[0]
val := keyval[1]
switch key {
case "control":
media.Control = val
case "rtpmap":
media.Rtpmap, _ = strconv.Atoi(val)
}
}
keyval = strings.Split(field, "/")
if len(keyval) >= 2 {
key := keyval[0]
switch strings.ToUpper(key) {
case "MPEG4-GENERIC":
media.Type = av.AAC
case "H264":
media.Type = av.H264
}
if i, err := strconv.Atoi(keyval[1]); err == nil {
media.TimeScale = i
}
if false {
fmt.Println("sdp:", keyval[1], media.TimeScale)
}
}
keyval = strings.Split(field, ";")
if len(keyval) > 1 {
for _, field := range keyval {
keyval := strings.SplitN(field, "=", 2)
if len(keyval) == 2 {
key := strings.TrimSpace(keyval[0])
val := keyval[1]
switch key {
case "config":
media.Config, _ = hex.DecodeString(val)
case "sizelength":
media.SizeLength, _ = strconv.Atoi(val)
case "indexlength":
media.IndexLength, _ = strconv.Atoi(val)
case "sprop-parameter-sets":
fields := strings.Split(val, ",")
for _, field := range fields {
val, _ := base64.StdEncoding.DecodeString(field)
media.SpropParameterSets = append(media.SpropParameterSets, val)
}
}
}
}
}
}
}
}
}
}
return
}

View File

@@ -0,0 +1,44 @@
package sdp
import (
"testing"
)
func TestParse(t *testing.T) {
infos := Decode(`
v=0
o=- 1459325504777324 1 IN IP4 192.168.0.123
s=RTSP/RTP stream from Network Video Server
i=mpeg4cif
t=0 0
a=tool:LIVE555 Streaming Media v2009.09.28
a=type:broadcast
a=control:*
a=range:npt=0-
a=x-qt-text-nam:RTSP/RTP stream from Network Video Server
a=x-qt-text-inf:mpeg4cif
m=video 0 RTP/AVP 96
c=IN IP4 0.0.0.0
b=AS:300
a=rtpmap:96 H264/90000
a=fmtp:96 profile-level-id=420029; packetization-mode=1; sprop-parameter-sets=Z00AHpWoKA9k,aO48gA==
a=x-dimensions: 720, 480
a=x-framerate: 15
a=control:track1
m=audio 0 RTP/AVP 96
c=IN IP4 0.0.0.0
b=AS:256
a=rtpmap:96 MPEG4-GENERIC/16000/2
a=fmtp:96 streamtype=5;profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3;config=1408
a=control:track2
m=audio 0 RTP/AVP 0
c=IN IP4 0.0.0.0
b=AS:50
a=recvonly
a=control:rtsp://109.195.127.207:554/mpeg4cif/trackID=2
a=rtpmap:0 PCMU/8000
a=Media_header:MEDIAINFO=494D4B48010100000400010010710110401F000000FA000000000000000000000000000000000000;
a=appversion:1.0
`)
t.Logf("%v", infos)
}

29
format/rtsp/stream.go Normal file
View File

@@ -0,0 +1,29 @@
package rtsp
import (
"time"
"github.com/deepch/vdk/av"
"github.com/deepch/vdk/format/rtsp/sdp"
)
type Stream struct {
av.CodecData
Sdp sdp.Media
client *Client
// h264
fuStarted bool
fuBuffer []byte
sps []byte
pps []byte
spsChanged bool
ppsChanged bool
gotpkt bool
pkt av.Packet
timestamp uint32
firsttimestamp uint32
lasttime time.Duration
}