mirror of https://bitbucket.org/ausocean/av.git
Merge branch 'master' into audio-compression
Making sure everything is up to date
This commit is contained in:
commit
2dc6032564
|
@ -109,25 +109,26 @@ func handleFlags() revid.Config {
|
||||||
inputCodecPtr = flag.String("InputCodec", "", "The codec of the input: H264, Mjpeg")
|
inputCodecPtr = flag.String("InputCodec", "", "The codec of the input: H264, Mjpeg")
|
||||||
rtmpMethodPtr = flag.String("RtmpMethod", "", "The method used to send over rtmp: Ffmpeg, Librtmp")
|
rtmpMethodPtr = flag.String("RtmpMethod", "", "The method used to send over rtmp: Ffmpeg, Librtmp")
|
||||||
packetizationPtr = flag.String("Packetization", "", "The method of data packetisation: Flv, Mpegts, None")
|
packetizationPtr = flag.String("Packetization", "", "The method of data packetisation: Flv, Mpegts, None")
|
||||||
quantizePtr = flag.Bool("Quantize", false, "Quantize input (non-variable bitrate)")
|
|
||||||
verbosityPtr = flag.String("Verbosity", "Info", "Verbosity: Info, Warning, Error, Fatal")
|
|
||||||
framesPerClipPtr = flag.Uint("FramesPerClip", 0, "Number of frames per clip sent")
|
|
||||||
rtmpUrlPtr = flag.String("RtmpUrl", "", "Url of rtmp endpoint")
|
|
||||||
bitratePtr = flag.Uint("Bitrate", 0, "Bitrate of recorded video")
|
|
||||||
outputPathPtr = flag.String("OutputPath", "", "The directory of the output file")
|
|
||||||
inputFilePtr = flag.String("InputPath", "", "The directory of the input file")
|
|
||||||
heightPtr = flag.Uint("Height", 0, "Height in pixels")
|
|
||||||
widthPtr = flag.Uint("Width", 0, "Width in pixels")
|
|
||||||
frameRatePtr = flag.Uint("FrameRate", 0, "Frame rate of captured video")
|
|
||||||
httpAddressPtr = flag.String("HttpAddress", "", "Destination address of http posts")
|
|
||||||
quantizationPtr = flag.Uint("Quantization", 0, "Desired quantization value: 0-40")
|
|
||||||
intraRefreshPeriodPtr = flag.Uint("IntraRefreshPeriod", 0, "The IntraRefreshPeriod i.e. how many keyframes we send")
|
|
||||||
verticalFlipPtr = flag.Bool("VerticalFlip", false, "Flip video vertically: Yes, No")
|
|
||||||
horizontalFlipPtr = flag.Bool("HorizontalFlip", false, "Flip video horizontally: Yes, No")
|
|
||||||
rtpAddrPtr = flag.String("RtpAddr", "", "Rtp destination address: <IP>:<port> (port is generally 6970-6999)")
|
rtpAddrPtr = flag.String("RtpAddr", "", "Rtp destination address: <IP>:<port> (port is generally 6970-6999)")
|
||||||
logPathPtr = flag.String("LogPath", defaultLogPath, "The log path")
|
logPathPtr = flag.String("LogPath", defaultLogPath, "The log path")
|
||||||
configFilePtr = flag.String("ConfigFile", "", "NetSender config file")
|
configFilePtr = flag.String("ConfigFile", "", "NetSender config file")
|
||||||
|
rtmpUrlPtr = flag.String("RtmpUrl", "", "Url of rtmp endpoint")
|
||||||
|
outputPathPtr = flag.String("OutputPath", "", "The directory of the output file")
|
||||||
|
inputFilePtr = flag.String("InputPath", "", "The directory of the input file")
|
||||||
|
verbosityPtr = flag.String("Verbosity", "Info", "Verbosity: Info, Warning, Error, Fatal")
|
||||||
|
httpAddressPtr = flag.String("HttpAddress", "", "Destination address of http posts")
|
||||||
|
quantizePtr = flag.Bool("Quantize", false, "Quantize input (non-variable bitrate)")
|
||||||
sendRetryPtr = flag.Bool("retry", false, "Specify whether a failed send should be retried.")
|
sendRetryPtr = flag.Bool("retry", false, "Specify whether a failed send should be retried.")
|
||||||
|
verticalFlipPtr = flag.Bool("VerticalFlip", false, "Flip video vertically: Yes, No")
|
||||||
|
horizontalFlipPtr = flag.Bool("HorizontalFlip", false, "Flip video horizontally: Yes, No")
|
||||||
|
framesPerClipPtr = flag.Uint("FramesPerClip", 0, "Number of frames per clip sent")
|
||||||
|
bitratePtr = flag.Uint("Bitrate", 0, "Bitrate of recorded video")
|
||||||
|
heightPtr = flag.Uint("Height", 0, "Height in pixels")
|
||||||
|
widthPtr = flag.Uint("Width", 0, "Width in pixels")
|
||||||
|
frameRatePtr = flag.Uint("FrameRate", 0, "Frame rate of captured video")
|
||||||
|
quantizationPtr = flag.Uint("Quantization", 0, "Desired quantization value: 0-40")
|
||||||
|
intraRefreshPeriodPtr = flag.Uint("IntraRefreshPeriod", 0, "The IntraRefreshPeriod i.e. how many keyframes we send")
|
||||||
|
rotationPtr = flag.Uint("Rotatation", 0, "Rotate video output. (0-359 degrees)")
|
||||||
)
|
)
|
||||||
|
|
||||||
var outputs flagStrings
|
var outputs flagStrings
|
||||||
|
@ -239,6 +240,7 @@ func handleFlags() revid.Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.Quantize = *quantizePtr
|
cfg.Quantize = *quantizePtr
|
||||||
|
cfg.Rotation = *rotationPtr
|
||||||
cfg.FlipHorizontal = *horizontalFlipPtr
|
cfg.FlipHorizontal = *horizontalFlipPtr
|
||||||
cfg.FlipVertical = *verticalFlipPtr
|
cfg.FlipVertical = *verticalFlipPtr
|
||||||
cfg.FramesPerClip = *framesPerClipPtr
|
cfg.FramesPerClip = *framesPerClipPtr
|
||||||
|
@ -267,10 +269,10 @@ func run(cfg revid.Config) {
|
||||||
readPin := func(pin *netsender.Pin) error {
|
readPin := func(pin *netsender.Pin) error {
|
||||||
switch {
|
switch {
|
||||||
case pin.Name == "X23":
|
case pin.Name == "X23":
|
||||||
if rv == nil {
|
|
||||||
pin.Value = -1
|
pin.Value = -1
|
||||||
}
|
if rv != nil {
|
||||||
pin.Value = rv.Bitrate()
|
pin.Value = rv.Bitrate()
|
||||||
|
}
|
||||||
case pin.Name[0] == 'X':
|
case pin.Name[0] == 'X':
|
||||||
return sds.ReadSystem(pin)
|
return sds.ReadSystem(pin)
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -69,6 +69,7 @@ type Config struct {
|
||||||
Logger Logger
|
Logger Logger
|
||||||
SendRetry bool
|
SendRetry bool
|
||||||
BurstPeriod uint
|
BurstPeriod uint
|
||||||
|
Rotation uint
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enums for config struct
|
// Enums for config struct
|
||||||
|
@ -116,6 +117,7 @@ const (
|
||||||
defaultVerbosity = No // FIXME(kortschak): This makes no sense whatsoever. No is currently 15.
|
defaultVerbosity = No // FIXME(kortschak): This makes no sense whatsoever. No is currently 15.
|
||||||
defaultRtpAddr = "localhost:6970"
|
defaultRtpAddr = "localhost:6970"
|
||||||
defaultBurstPeriod = 10 // Seconds
|
defaultBurstPeriod = 10 // Seconds
|
||||||
|
defaultRotation = 0 // Degrees
|
||||||
)
|
)
|
||||||
|
|
||||||
// Validate checks for any errors in the config fields and defaults settings
|
// Validate checks for any errors in the config fields and defaults settings
|
||||||
|
@ -215,6 +217,11 @@ func (c *Config) Validate(r *Revid) error {
|
||||||
c.FramesPerClip = defaultFramesPerClip
|
c.FramesPerClip = defaultFramesPerClip
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.Rotation > 359 {
|
||||||
|
c.Logger.Log(logger.Warning, pkg+"bad rotate angle, defaulting", "angle", defaultRotation)
|
||||||
|
c.Rotation = defaultRotation
|
||||||
|
}
|
||||||
|
|
||||||
if c.Width == 0 {
|
if c.Width == 0 {
|
||||||
c.Logger.Log(logger.Info, pkg+"no width defined, defaulting", "width", defaultWidth)
|
c.Logger.Log(logger.Info, pkg+"no width defined, defaulting", "width", defaultWidth)
|
||||||
c.Width = defaultWidth
|
c.Width = defaultWidth
|
||||||
|
|
|
@ -433,6 +433,13 @@ func (r *Revid) Update(vars map[string]string) error {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
r.config.FrameRate = uint(v)
|
r.config.FrameRate = uint(v)
|
||||||
|
case "Rotation":
|
||||||
|
v, err := strconv.ParseUint(value, 10, 0)
|
||||||
|
if err != nil || v > 359 {
|
||||||
|
r.config.Logger.Log(logger.Warning, pkg+"invalid rotation param", "value", value)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
r.config.Rotation = uint(v)
|
||||||
case "HttpAddress":
|
case "HttpAddress":
|
||||||
r.config.HttpAddress = value
|
r.config.HttpAddress = value
|
||||||
case "Quantization":
|
case "Quantization":
|
||||||
|
@ -449,6 +456,7 @@ func (r *Revid) Update(vars map[string]string) error {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
r.config.IntraRefreshPeriod = uint(p)
|
r.config.IntraRefreshPeriod = uint(p)
|
||||||
|
|
||||||
case "HorizontalFlip":
|
case "HorizontalFlip":
|
||||||
switch strings.ToLower(value) {
|
switch strings.ToLower(value) {
|
||||||
case "true":
|
case "true":
|
||||||
|
@ -585,13 +593,16 @@ func (r *Revid) startRaspivid() error {
|
||||||
"--height", fmt.Sprint(r.config.Height),
|
"--height", fmt.Sprint(r.config.Height),
|
||||||
"--bitrate", fmt.Sprint(r.config.Bitrate),
|
"--bitrate", fmt.Sprint(r.config.Bitrate),
|
||||||
"--framerate", fmt.Sprint(r.config.FrameRate),
|
"--framerate", fmt.Sprint(r.config.FrameRate),
|
||||||
|
"--rotation", fmt.Sprint(r.config.Rotation),
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.config.FlipVertical {
|
||||||
|
args = append(args, "--vflip")
|
||||||
}
|
}
|
||||||
if r.config.FlipHorizontal {
|
if r.config.FlipHorizontal {
|
||||||
args = append(args, "--hflip")
|
args = append(args, "--hflip")
|
||||||
}
|
}
|
||||||
if r.config.FlipVertical {
|
|
||||||
args = append(args, "--vflip")
|
|
||||||
}
|
|
||||||
switch r.config.InputCodec {
|
switch r.config.InputCodec {
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("revid: invalid input codec: %v", r.config.InputCodec)
|
return fmt.Errorf("revid: invalid input codec: %v", r.config.InputCodec)
|
||||||
|
@ -638,14 +649,7 @@ func (r *Revid) startV4L() error {
|
||||||
"-f", "h264",
|
"-f", "h264",
|
||||||
"-r", fmt.Sprint(r.config.FrameRate),
|
"-r", fmt.Sprint(r.config.FrameRate),
|
||||||
}
|
}
|
||||||
switch {
|
|
||||||
case r.config.FlipHorizontal && r.config.FlipVertical:
|
|
||||||
args = append(args, "-vf", "hflip,vflip")
|
|
||||||
case r.config.FlipHorizontal:
|
|
||||||
args = append(args, "-vf", "hflip")
|
|
||||||
case r.config.FlipVertical:
|
|
||||||
args = append(args, "-vf", "vflip")
|
|
||||||
}
|
|
||||||
args = append(args,
|
args = append(args,
|
||||||
"-b:v", fmt.Sprint(r.config.Bitrate),
|
"-b:v", fmt.Sprint(r.config.Bitrate),
|
||||||
"-maxrate", fmt.Sprint(r.config.Bitrate),
|
"-maxrate", fmt.Sprint(r.config.Bitrate),
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
package revid
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"bitbucket.org/ausocean/iot/pi/netsender"
|
||||||
|
)
|
||||||
|
|
||||||
|
const raspividPath = "/usr/local/bin/raspivid"
|
||||||
|
|
||||||
|
// Suppress all test logging, except for t.Errorf output.
|
||||||
|
var silent bool
|
||||||
|
|
||||||
|
// TestRaspivid tests that raspivid starts correctly.
|
||||||
|
// It is intended to be run on a Raspberry Pi.
|
||||||
|
func TestRaspivid(t *testing.T) {
|
||||||
|
if _, err := os.Stat(raspividPath); os.IsNotExist(err) {
|
||||||
|
t.Skip("Skipping TestRaspivid since no raspivid found.")
|
||||||
|
}
|
||||||
|
|
||||||
|
var logger testLogger
|
||||||
|
ns, err := netsender.New(&logger, nil, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("netsender.New failed with error %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var c Config
|
||||||
|
c.Logger = &logger
|
||||||
|
c.Input = Raspivid
|
||||||
|
c.Outputs = make([]uint8, 1)
|
||||||
|
|
||||||
|
rv, err := New(c, ns)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("revid.New failed with error %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = rv.Start()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("revid.Start failed with error %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// testLogger implements a netsender.Logger.
|
||||||
|
type testLogger struct{}
|
||||||
|
|
||||||
|
// SetLevel normally sets the logging level, but it is a no-op in our case.
|
||||||
|
func (tl *testLogger) SetLevel(level int8) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log requests the Logger to write a message at the given level.
|
||||||
|
func (tl *testLogger) Log(level int8, msg string, params ...interface{}) {
|
||||||
|
logLevels := [...]string{"Debug", "Info", "Warn", "Error", "", "", "Fatal"}
|
||||||
|
if level < -1 || level > 5 {
|
||||||
|
panic("Invalid log level")
|
||||||
|
}
|
||||||
|
if !silent {
|
||||||
|
fmt.Printf("%s: %s\n", logLevels[level+1], msg)
|
||||||
|
}
|
||||||
|
if level == 5 {
|
||||||
|
buf := make([]byte, 1<<16)
|
||||||
|
size := runtime.Stack(buf, true)
|
||||||
|
fmt.Printf("%s\n", string(buf[:size]))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue