mirror of https://bitbucket.org/ausocean/av.git
revid: fixing some more bugs
Fixed H264 RTP extractor. Fine tuned some timing regarding geovision setup. Added some more logging to geovision setup.
This commit is contained in:
parent
f336a03d7a
commit
38cfad7b67
|
@ -158,7 +158,7 @@ func handleFlags() revid.Config {
|
|||
cfg.LogLevel = defaultLogVerbosity
|
||||
}
|
||||
|
||||
log = logger.New(cfg.LogLevel, &smartlogger.New(*logPathPtr).LogRoller)
|
||||
log = logger.New(cfg.LogLevel, &smartlogger.New(*logPathPtr).LogRoller, true)
|
||||
|
||||
cfg.Logger = log
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@ import (
|
|||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"bitbucket.org/ausocean/av/codec/h264/h264dec"
|
||||
|
@ -98,7 +97,7 @@ func (e *Extracter) Extract(dst io.Writer, src io.Reader, delay time.Duration) e
|
|||
n, err := src.Read(buf)
|
||||
switch {
|
||||
case err == nil: // Do nothing.
|
||||
case err == io.EOF || err.(net.Error).Timeout():
|
||||
case err == io.EOF:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("source read error: %v\n", err)
|
||||
|
@ -208,7 +207,7 @@ func (e *Extracter) handleFUA(d []byte) {
|
|||
func (e *Extracter) writeWithPrefix(d []byte) {
|
||||
e.toWrite = append(e.toWrite, d...)
|
||||
curType, _ := NALType(e.toWrite)
|
||||
if e.buf.Len() != 0 && (curType == h264dec.NALTypeIDR || curType == h264dec.NALTypeNonIDR) {
|
||||
if e.buf.Len() != 0 && (curType == h264dec.NALTypeSPS || curType == h264dec.NALTypeIDR || curType == h264dec.NALTypeNonIDR) {
|
||||
e.buf.WriteTo(e.dst)
|
||||
e.buf.Reset()
|
||||
e.buf.Write(aud)
|
||||
|
|
3
go.mod
3
go.mod
|
@ -5,7 +5,7 @@ go 1.13
|
|||
require (
|
||||
bitbucket.org/ausocean/iot v1.2.7
|
||||
bitbucket.org/ausocean/test v0.0.0-20190821085226-7a524f2344ba
|
||||
bitbucket.org/ausocean/utils v1.2.9
|
||||
bitbucket.org/ausocean/utils v1.2.10
|
||||
github.com/BurntSushi/toml v0.3.1 // indirect
|
||||
github.com/Comcast/gots v0.0.0-20190305015453-8d56e473f0f7
|
||||
github.com/go-audio/audio v0.0.0-20181013203223-7b2a6ca21480
|
||||
|
@ -13,5 +13,6 @@ require (
|
|||
github.com/mewkiz/flac v1.0.5
|
||||
github.com/pkg/errors v0.8.1
|
||||
github.com/yobert/alsa v0.0.0-20180630182551-d38d89fa843e
|
||||
gocv.io/x/gocv v0.21.0
|
||||
gopkg.in/yaml.v2 v2.2.2 // indirect
|
||||
)
|
||||
|
|
7
go.sum
7
go.sum
|
@ -1,15 +1,20 @@
|
|||
bitbucket.org/ausocean/av v0.0.0-20190416003121-6ee286e98874/go.mod h1:DxZEprrNNQ2slHKAQVUHryDaWc5CbjxyHAvomhzg+AE=
|
||||
bitbucket.org/ausocean/av/input/gvctrl v0.0.0-20191017223116-ce6c12cce8cd h1:L99pvZZtdy3v54ym6GswYi8SOGgz+4Tr8hiIOI+nSiQ=
|
||||
bitbucket.org/ausocean/av/input/gvctrl v0.0.0-20191017223116-ce6c12cce8cd/go.mod h1:Hg522DOVaj23J7CIxknCxmNsLGdg1iZ+Td1FDcTOdLQ=
|
||||
bitbucket.org/ausocean/iot v1.2.4/go.mod h1:5HVLgPHccW2PxS7WDUQO6sKWMgk3Vfze/7d5bHs8EWU=
|
||||
bitbucket.org/ausocean/iot v1.2.6 h1:KAAY1KZDbyOpoKajT1dM8BawupHiW9hUOelseSV1Ptc=
|
||||
bitbucket.org/ausocean/iot v1.2.6/go.mod h1:71AYHh8yGZ8XyzDBskwIWMF+8E8ORagXpXE24wlhoE0=
|
||||
bitbucket.org/ausocean/iot v1.2.7 h1:dZgrmVtuXnzHgybDthn0bYgAJms9euTONXBsqsx9g5M=
|
||||
bitbucket.org/ausocean/iot v1.2.7/go.mod h1:aAWgPo2f8sD2OPmxae1E5/iD9+tKY/iW4pcQMQXUvHM=
|
||||
bitbucket.org/ausocean/test v0.0.0-20190821085226-7a524f2344ba/go.mod h1:MbKtu9Pu8l3hiVGX6ep8S1VwAVY5uCbifCFOYsm914w=
|
||||
bitbucket.org/ausocean/utils v0.0.0-20190408050157-66d3b4d4041e/go.mod h1:uXzX9z3PLemyURTMWRhVI8uLhPX4uuvaaO85v2hcob8=
|
||||
bitbucket.org/ausocean/utils v1.2.6/go.mod h1:uXzX9z3PLemyURTMWRhVI8uLhPX4uuvaaO85v2hcob8=
|
||||
bitbucket.org/ausocean/utils v1.2.8 h1:hyxAIqYBqjqCguG+6A/kKyrAihyeUt2LziZg6CH0gLU=
|
||||
bitbucket.org/ausocean/utils v1.2.8/go.mod h1:uXzX9z3PLemyURTMWRhVI8uLhPX4uuvaaO85v2hcob8=
|
||||
bitbucket.org/ausocean/utils v1.2.9 h1:g45C6KCNvCLOGFv+ZnmDbQOOdnwpIsvzuNOD141CTVI=
|
||||
bitbucket.org/ausocean/utils v1.2.9/go.mod h1:uXzX9z3PLemyURTMWRhVI8uLhPX4uuvaaO85v2hcob8=
|
||||
bitbucket.org/ausocean/utils v1.2.10 h1:JTS7n+K+0o/FQFWKjdGgA1ElZ4TQu9aHX3wTJXOayXw=
|
||||
bitbucket.org/ausocean/utils v1.2.10/go.mod h1:uXzX9z3PLemyURTMWRhVI8uLhPX4uuvaaO85v2hcob8=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Comcast/gots v0.0.0-20190305015453-8d56e473f0f7 h1:LdOc9B9Bj6LEsKiXShkLA3/kpxXb6LJpH+ekU2krbzw=
|
||||
|
@ -55,6 +60,8 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/
|
|||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
gocv.io/x/gocv v0.21.0 h1:dVjagrupZrfCRY0qPEaYWgoNMRpBel6GYDH4mvQOK8Y=
|
||||
gocv.io/x/gocv v0.21.0/go.mod h1:Rar2PS6DV+T4FL+PM535EImD/h13hGVaHhnCu1xarBs=
|
||||
golang.org/x/sys v0.0.0-20190305064518-30e92a19ae4a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
|
|
@ -121,7 +121,7 @@ type PacketReader struct {
|
|||
|
||||
// Read implements io.Reader.
|
||||
func (r PacketReader) Read(b []byte) (int, error) {
|
||||
const readTimeout = time.Second
|
||||
const readTimeout = 5 * time.Second
|
||||
err := r.PacketConn.SetReadDeadline(time.Now().Add(readTimeout))
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("could not set read deadline for PacketConn: %w", err)
|
||||
|
|
|
@ -133,10 +133,11 @@ func (r *Revid) startV4L() (func() error, error) {
|
|||
"-r", fmt.Sprint(r.config.FrameRate),
|
||||
}
|
||||
|
||||
br := r.config.Bitrate * 1000
|
||||
args = append(args,
|
||||
"-b:v", fmt.Sprint(r.config.Bitrate),
|
||||
"-maxrate", fmt.Sprint(r.config.Bitrate),
|
||||
"-bufsize", fmt.Sprint(r.config.Bitrate/2),
|
||||
"-b:v", fmt.Sprint(br),
|
||||
"-maxrate", fmt.Sprint(br),
|
||||
"-bufsize", fmt.Sprint(br/2),
|
||||
"-s", fmt.Sprintf("%dx%d", r.config.Width, r.config.Height),
|
||||
"-",
|
||||
)
|
||||
|
@ -179,7 +180,12 @@ func (r *Revid) setupInputForFile() (func() error, error) {
|
|||
// startRTSPCamera uses RTSP to request an RTP stream from an IP camera. An RTP
|
||||
// client is created from which RTP packets containing either h264/h265 can be
|
||||
// read by the selected lexer.
|
||||
//
|
||||
// TODO(saxon): this function should really be startGeoVision. It's much too
|
||||
// specific to be called startRTSPCamera.
|
||||
func (r *Revid) startRTSPCamera() (func() error, error) {
|
||||
r.config.Logger.Log(logger.Info, pkg+"starting geovision...")
|
||||
|
||||
err := gvctrl.Set(
|
||||
r.config.CameraIP,
|
||||
gvctrl.CodecOut(
|
||||
|
@ -202,45 +208,48 @@ func (r *Revid) startRTSPCamera() (func() error, error) {
|
|||
}[r.config.VBRQuality],
|
||||
),
|
||||
gvctrl.VBRBitrate(r.config.VBRBitrate),
|
||||
gvctrl.CBRBitrate(int(r.config.Bitrate)/1000),
|
||||
gvctrl.CBRBitrate(int(r.config.Bitrate)),
|
||||
gvctrl.Refresh(float64(r.config.MinFrames)/float64(r.config.FrameRate)),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not set IPCamera settings: %w", err)
|
||||
}
|
||||
|
||||
r.config.Logger.Log(logger.Info, pkg+"completed geovision configuration")
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
rtspClt, local, remote, err := rtsp.NewClient("rtsp://" + ipCamUser + ":" + ipCamPass + "@" + r.config.CameraIP + ":8554/" + "CH002.sdp")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r.config.Logger.Log(logger.Info, pkg+"created RTSP client")
|
||||
|
||||
resp, err := rtspClt.Options()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r.config.Logger.Log(logger.Info, pkg+"RTSP OPTIONS response", "response", resp.String())
|
||||
r.config.Logger.Log(logger.Debug, pkg+"RTSP OPTIONS response", "response", resp.String())
|
||||
|
||||
resp, err = rtspClt.Describe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r.config.Logger.Log(logger.Info, pkg+"RTSP DESCRIBE response", "response", resp.String())
|
||||
r.config.Logger.Log(logger.Debug, pkg+"RTSP DESCRIBE response", "response", resp.String())
|
||||
|
||||
resp, err = rtspClt.Setup("track1", fmt.Sprintf("RTP/AVP;unicast;client_port=%d-%d", rtpPort, rtcpPort))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r.config.Logger.Log(logger.Info, pkg+"RTSP SETUP response", "response", resp.String())
|
||||
r.config.Logger.Log(logger.Debug, pkg+"RTSP SETUP response", "response", resp.String())
|
||||
|
||||
rtpCltAddr, rtcpCltAddr, rtcpSvrAddr, err := formAddrs(local, remote, *resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err = rtspClt.Play()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r.config.Logger.Log(logger.Info, pkg+"RTSP server PLAY response", "response", resp.String())
|
||||
r.config.Logger.Log(logger.Info, pkg+"RTSP session setup complete")
|
||||
|
||||
rtpClt, err := rtp.NewClient(rtpCltAddr)
|
||||
if err != nil {
|
||||
|
@ -252,6 +261,8 @@ func (r *Revid) startRTSPCamera() (func() error, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
r.config.Logger.Log(logger.Info, pkg+"RTCP and RTP clients created")
|
||||
|
||||
// Check errors from RTCP client until it has stopped running.
|
||||
go func() {
|
||||
for {
|
||||
|
@ -267,10 +278,21 @@ func (r *Revid) startRTSPCamera() (func() error, error) {
|
|||
// Start the RTCP client.
|
||||
rtcpClt.Start()
|
||||
|
||||
r.config.Logger.Log(logger.Info, pkg+"RTCP client started")
|
||||
|
||||
// Start reading data from the RTP client.
|
||||
r.wg.Add(1)
|
||||
go r.processFrom(rtpClt, time.Second/time.Duration(r.config.FrameRate))
|
||||
|
||||
r.config.Logger.Log(logger.Info, pkg+"started input processor")
|
||||
|
||||
resp, err = rtspClt.Play()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r.config.Logger.Log(logger.Debug, pkg+"RTSP server PLAY response", "response", resp.String())
|
||||
r.config.Logger.Log(logger.Info, pkg+"play requested, now receiving stream")
|
||||
|
||||
return func() error {
|
||||
err := rtpClt.Close()
|
||||
if err != nil {
|
||||
|
@ -283,6 +305,8 @@ func (r *Revid) startRTSPCamera() (func() error, error) {
|
|||
}
|
||||
|
||||
rtcpClt.Stop()
|
||||
|
||||
r.config.Logger.Log(logger.Info, pkg+"RTP, RTSP and RTCP clients stopped and closed")
|
||||
return nil
|
||||
}, nil
|
||||
}
|
||||
|
@ -319,8 +343,7 @@ func parseSvrRTCPPort(resp rtsp.Response) (int, error) {
|
|||
// processFrom is run as a routine to read from a input data source, lex and
|
||||
// then send individual access units to revid's encoders.
|
||||
func (r *Revid) processFrom(read io.Reader, delay time.Duration) {
|
||||
r.config.Logger.Log(logger.Info, pkg+"reading input data")
|
||||
r.err <- r.lexTo(r.encoders, read, delay)
|
||||
r.config.Logger.Log(logger.Info, pkg+"finished reading input data")
|
||||
r.config.Logger.Log(logger.Info, pkg+"finished lexing")
|
||||
r.wg.Done()
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ const (
|
|||
defaultServerRTCPPort = 17301
|
||||
)
|
||||
|
||||
const pkg = "revid:"
|
||||
const pkg = "revid: "
|
||||
|
||||
type Logger interface {
|
||||
SetLevel(int8)
|
||||
|
|
|
@ -219,6 +219,7 @@ func (s *mtsSender) output() {
|
|||
chunk = nil
|
||||
continue
|
||||
}
|
||||
s.log(logger.Debug, pkg+"mtsSender: writing")
|
||||
_, err = s.dst.Write(chunk.Bytes())
|
||||
if err != nil {
|
||||
s.repairer.Failed()
|
||||
|
|
Loading…
Reference in New Issue