mirror of https://bitbucket.org/ausocean/av.git
revid: revid config to update geovision configuration using gvctrl
Added required new params to config structure, and therefore also added new defaults and validation checking. Also updated revid's update func so that we can control new parameters using vars. Now using gvctrl in startRTSPCamera function and interpreting revid config to configure camera.
This commit is contained in:
parent
ce6c12cce8
commit
8c1c192218
|
@ -109,7 +109,7 @@ func handleFlags() revid.Config {
|
|||
cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`")
|
||||
inputCodecPtr = flag.String("InputCodec", "H264", "The codec of the input: H264, Mjpeg, PCM, ADPCM")
|
||||
inputPtr = flag.String("Input", "", "The input type: Raspivid, File, v4l, Audio, RTSP")
|
||||
rtspURLPtr = flag.String("RTSPURL", "", "The URL for an RTSP server.")
|
||||
cameraIPPtr = flag.String("CameraIP", "", "The the IP of the RTSP server")
|
||||
verbosityPtr = flag.String("Verbosity", "Info", "Verbosity: Debug, Info, Warning, Error, Fatal")
|
||||
rtpAddrPtr = flag.String("RtpAddr", "", "Rtp destination address: <IP>:<port> (port is generally 6970-6999)")
|
||||
logPathPtr = flag.String("LogPath", defaultLogPath, "The log path")
|
||||
|
@ -231,7 +231,7 @@ func handleFlags() revid.Config {
|
|||
netsender.ConfigFile = *configFilePtr
|
||||
}
|
||||
|
||||
cfg.RTSPURL = *rtspURLPtr
|
||||
cfg.CameraIP = *cameraIPPtr
|
||||
cfg.Rotation = *rotationPtr
|
||||
cfg.FlipHorizontal = *horizontalFlipPtr
|
||||
cfg.FlipVertical = *verticalFlipPtr
|
||||
|
|
|
@ -63,6 +63,19 @@ var AutoWhiteBalanceModes = [...]string{
|
|||
"horizon",
|
||||
}
|
||||
|
||||
// quality represents video quality.
|
||||
type quality int
|
||||
|
||||
// The different video qualities that can be used for variable bitrate when
|
||||
// using the GeoVision camera.
|
||||
const (
|
||||
qualityStandard quality = iota
|
||||
qualityFair
|
||||
qualityGood
|
||||
qualityGreat
|
||||
qualityExcellent
|
||||
)
|
||||
|
||||
// Enums to define inputs, outputs and codecs.
|
||||
const (
|
||||
// Indicates no option has been set.
|
||||
|
@ -100,8 +113,11 @@ const (
|
|||
defaultInputCodec = codecutil.H264
|
||||
defaultVerbosity = logger.Error
|
||||
defaultRtpAddr = "localhost:6970"
|
||||
defaultRTSPURL = "rtsp://admin:admin@192.168.1.50:8554/CH001.sdp"
|
||||
defaultBurstPeriod = 10 // Seconds
|
||||
defaultCameraIP = "192.168.1.50"
|
||||
defaultVBR = false
|
||||
defaultVBRQuality = qualityStandard
|
||||
defaultBurstPeriod = 10 // Seconds
|
||||
defaultVBRBitrate = 500 // kbps
|
||||
|
||||
// Raspivid video defaults.
|
||||
defaultBrightness = 50
|
||||
|
@ -113,7 +129,7 @@ const (
|
|||
defaultMinFrames = 100
|
||||
defaultClipDuration = 0
|
||||
defaultQuantization = 30
|
||||
defaultBitrate = 400000
|
||||
defaultBitrate = 400
|
||||
|
||||
// Audio defaults.
|
||||
defaultAudioInputCodec = codecutil.ADPCM
|
||||
|
@ -152,7 +168,7 @@ type Config struct {
|
|||
// File:
|
||||
// Location must be specified in InputPath field.
|
||||
// RTSP:
|
||||
// RTSPURL must also be defined.
|
||||
// CameraIP should also be defined.
|
||||
Input uint8
|
||||
|
||||
// InputCodec defines the input codec we wish to use, and therefore defines the
|
||||
|
@ -181,9 +197,9 @@ type Config struct {
|
|||
// RTMP is to be used as an output.
|
||||
RTMPURL string
|
||||
|
||||
// RTSPURL specifies the RTSP server URL for RTSP input. This must be defined
|
||||
// when Input is RTSP.
|
||||
RTSPURL string
|
||||
// CameraIP is the IP address of the camera in the case of the input camera
|
||||
// being an IP camera.
|
||||
CameraIP string
|
||||
|
||||
// OutputPath defines the output destination for File output. This must be
|
||||
// defined if File output is to be used.
|
||||
|
@ -204,11 +220,27 @@ type Config struct {
|
|||
// defined in /etc/netsender.conf.
|
||||
HTTPAddress string
|
||||
|
||||
// Quantization defines the quantization level, which may be a value between
|
||||
// 0-40. This will only take effect if the Quantize field is true and if we
|
||||
// are using Raspivid input.
|
||||
// VBR indicates whether we wish to use constant or variable bitrate. If VBR
|
||||
// is true then we will use variable bitrate, and constant bitrate otherwise.
|
||||
// In the case of the Pi camera, variable bitrate quality is controlled by
|
||||
// the Quantization parameter below. In the case of the GeoVision camera,
|
||||
// variable bitrate quality is controlled by firstly the VBRQuality parameter
|
||||
// and second the VBRBitrate parameter.
|
||||
VBR bool
|
||||
|
||||
// Quantization defines the quantization level, which will determine variable
|
||||
// bitrate quality in the case of input from the Pi Camera.
|
||||
Quantization uint
|
||||
|
||||
// VBRQuality describes the general quality of video from the GeoVision camera
|
||||
// under variable bitrate. VBRQuality can be one 5 consts defined:
|
||||
// qualityStandard, qualityFair, qualityGood, qualityGreat and qualityExcellent.
|
||||
VBRQuality quality
|
||||
|
||||
// VBRBitrate describes maximal bitrate for the GeoVision camera when under
|
||||
// variable bitrate.
|
||||
VBRBitrate int
|
||||
|
||||
// MinFrames defines the frequency of key NAL units SPS, PPS and IDR in
|
||||
// number of NAL units. This will also determine the frequency of PSI if the
|
||||
// output container is MPEG-TS. If ClipDuration is less than MinFrames,
|
||||
|
@ -251,7 +283,7 @@ type Config struct {
|
|||
Rotation uint // Rotation defines the video rotation angle in degrees Raspivid input.
|
||||
Height uint // Height defines the input video height Raspivid input.
|
||||
Width uint // Width defines the input video width Raspivid input.
|
||||
Bitrate uint // Bitrate specifies the input bitrate for Raspivid input.
|
||||
Bitrate uint // Bitrate specifies the bitrate for constant bitrate in kbps.
|
||||
FlipHorizontal bool // FlipHorizontal flips video horizontally for Raspivid input.
|
||||
FlipVertical bool // FlipVertial flips video vertically for Raspivid input.
|
||||
|
||||
|
@ -288,9 +320,9 @@ func (c *Config) Validate() error {
|
|||
switch c.Input {
|
||||
case Raspivid, V4L, File, Audio:
|
||||
case RTSP:
|
||||
if c.RTSPURL == "" {
|
||||
c.Logger.Log(logger.Info, pkg+"no RTSPURL defined, defaulting", "RTSPURL", defaultRTSPURL)
|
||||
c.RTSPURL = defaultRTSPURL
|
||||
if c.CameraIP == "" {
|
||||
c.Logger.Log(logger.Info, pkg+"no CameraIP defined, defaulting", "CameraIP", defaultCameraIP)
|
||||
c.CameraIP = defaultCameraIP
|
||||
}
|
||||
case NothingDefined:
|
||||
c.Logger.Log(logger.Info, pkg+"no input type defined, defaulting", "input", defaultInput)
|
||||
|
@ -481,6 +513,18 @@ func (c *Config) Validate() error {
|
|||
c.MTSRBWriteTimeout = defaultMTSRBWriteTimeout
|
||||
}
|
||||
|
||||
switch c.VBRQuality {
|
||||
case qualityStandard, qualityFair, qualityGood, qualityGreat, qualityExcellent:
|
||||
default:
|
||||
c.Logger.Log(logger.Info, pkg+"VBRQuality bad or unset, defaulting", "VBRQuality", defaultVBRQuality)
|
||||
c.VBRQuality = defaultVBRQuality
|
||||
}
|
||||
|
||||
if c.VBRBitrate <= 0 {
|
||||
c.Logger.Log(logger.Info, pkg+"VBRBitrate bad or unset, defaulting", "VBRBitrate", defaultVBRBitrate)
|
||||
c.VBRBitrate = defaultVBRBitrate
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -40,12 +40,19 @@ import (
|
|||
"time"
|
||||
|
||||
"bitbucket.org/ausocean/av/codec/codecutil"
|
||||
"bitbucket.org/ausocean/av/input/gvctrl"
|
||||
"bitbucket.org/ausocean/av/protocol/rtcp"
|
||||
"bitbucket.org/ausocean/av/protocol/rtp"
|
||||
"bitbucket.org/ausocean/av/protocol/rtsp"
|
||||
"bitbucket.org/ausocean/utils/logger"
|
||||
)
|
||||
|
||||
// TODO: remove this when gvctrl has configurable user and pass.
|
||||
const (
|
||||
ipCamUser = "admin"
|
||||
ipCamPass = "pass"
|
||||
)
|
||||
|
||||
// startRaspivid sets up things for input from raspivid i.e. starts
|
||||
// a raspivid process and pipes it's data output.
|
||||
func (r *Revid) startRaspivid() (func() error, error) {
|
||||
|
@ -58,7 +65,7 @@ func (r *Revid) startRaspivid() (func() error, error) {
|
|||
"--timeout", disabled,
|
||||
"--width", fmt.Sprint(r.config.Width),
|
||||
"--height", fmt.Sprint(r.config.Height),
|
||||
"--bitrate", fmt.Sprint(r.config.Bitrate),
|
||||
"--bitrate", fmt.Sprint(r.config.Bitrate * 1000), // Convert from kbps to bps.
|
||||
"--framerate", fmt.Sprint(r.config.FrameRate),
|
||||
"--rotation", fmt.Sprint(r.config.Rotation),
|
||||
"--brightness", fmt.Sprint(r.config.Brightness),
|
||||
|
@ -87,7 +94,7 @@ func (r *Revid) startRaspivid() (func() error, error) {
|
|||
"--inline",
|
||||
"--intra", fmt.Sprint(r.config.MinFrames),
|
||||
)
|
||||
if r.config.Quantization != 0 {
|
||||
if r.config.VBR {
|
||||
args = append(args, "-qp", fmt.Sprint(r.config.Quantization))
|
||||
}
|
||||
case codecutil.MJPEG:
|
||||
|
@ -173,7 +180,36 @@ func (r *Revid) setupInputForFile() (func() error, error) {
|
|||
// client is created from which RTP packets containing either h264/h265 can be
|
||||
// read by the selected lexer.
|
||||
func (r *Revid) startRTSPCamera() (func() error, error) {
|
||||
rtspClt, local, remote, err := rtsp.NewClient(r.config.RTSPURL)
|
||||
err := gvctrl.Set(
|
||||
r.config.CameraIP,
|
||||
gvctrl.CodecOut(
|
||||
map[uint8]gvctrl.Codec{
|
||||
codecutil.H264: gvctrl.CodecH264,
|
||||
codecutil.H265: gvctrl.CodecH265,
|
||||
codecutil.MJPEG: gvctrl.CodecMJPEG,
|
||||
}[r.config.InputCodec],
|
||||
),
|
||||
gvctrl.Height(int(r.config.Height)),
|
||||
gvctrl.FrameRate(int(r.config.FrameRate)),
|
||||
gvctrl.VariableBitrate(r.config.VBR),
|
||||
gvctrl.VBRQuality(
|
||||
map[quality]gvctrl.Quality{
|
||||
qualityStandard: gvctrl.QualityStandard,
|
||||
qualityFair: gvctrl.QualityFair,
|
||||
qualityGood: gvctrl.QualityGood,
|
||||
qualityGreat: gvctrl.QualityGreat,
|
||||
qualityExcellent: gvctrl.QualityExcellent,
|
||||
}[r.config.VBRQuality],
|
||||
),
|
||||
gvctrl.VBRBitrate(r.config.VBRBitrate),
|
||||
gvctrl.CBRBitrate(int(r.config.Bitrate)/1000),
|
||||
gvctrl.Refresh(float64(r.config.MinFrames)/float64(r.config.FrameRate)),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not set IPCamera settings: %w", err)
|
||||
}
|
||||
|
||||
rtspClt, local, remote, err := rtsp.NewClient("rtsp://" + ipCamUser + ":" + ipCamPass + "@" + r.config.CameraIP + ":8554/" + "CH002.sdp")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -618,6 +618,27 @@ func (r *Revid) Update(vars map[string]string) error {
|
|||
break
|
||||
}
|
||||
r.config.MTSRBWriteTimeout = v
|
||||
case "VBR":
|
||||
v, ok := map[string]bool{"true": true, "false": false}[strings.ToLower(value)]
|
||||
if !ok {
|
||||
r.config.Logger.Log(logger.Warning, pkg+"invalid VBR var", "value", value)
|
||||
break
|
||||
}
|
||||
r.config.VBR = v
|
||||
case "VBRQuality":
|
||||
v, ok := map[string]quality{"standard": qualityStandard, "fair": qualityFair, "good": qualityGood, "great": qualityGreat, "excellent": qualityExcellent}[strings.ToLower(value)]
|
||||
if !ok {
|
||||
r.config.Logger.Log(logger.Warning, pkg+"invalid VBRQuality var", "value", value)
|
||||
break
|
||||
}
|
||||
r.config.VBRQuality = v
|
||||
case "VBRBitrate":
|
||||
v, err := strconv.Atoi(value)
|
||||
if err != nil || v <= 0 {
|
||||
r.config.Logger.Log(logger.Warning, pkg+"invalid VBRBitrate var", "value", value)
|
||||
break
|
||||
}
|
||||
r.config.VBRBitrate = v
|
||||
}
|
||||
}
|
||||
r.config.Logger.Log(logger.Info, pkg+"revid config changed", "config", fmt.Sprintf("%+v", r.config))
|
||||
|
|
Loading…
Reference in New Issue