Builds and bugs are out (for now)

Let's try testing on the pi next
This commit is contained in:
Unknown 2018-01-31 12:53:18 +10:30
parent 7572968ad3
commit 147716ccab
2 changed files with 75 additions and 48 deletions

View File

@ -36,7 +36,6 @@ import (
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"net"
"net/http" "net/http"
"os" "os"
"os/exec" "os/exec"
@ -114,6 +113,8 @@ const (
defaultWidth = "1280" defaultWidth = "1280"
defaultHeight = "720" defaultHeight = "720"
defaultIntraRefreshPeriod = "100" defaultIntraRefreshPeriod = "100"
defaultTimeout = "0"
defaultQuantization = "35"
) )
// RevidInst provides methods to control a revidInst session; providing methods // RevidInst provides methods to control a revidInst session; providing methods
@ -149,31 +150,35 @@ type revidInst struct {
func NewRevidInstance(config Config) (r *revidInst, err error) { func NewRevidInstance(config Config) (r *revidInst, err error) {
r = new(revidInst) r = new(revidInst)
r.ringBuffer = ringbuffer.NewRingBuffer(bufferSize, mp2tPacketSize*mp2tMaxPackets) r.ringBuffer = ringbuffer.NewRingBuffer(bufferSize, mp2tPacketSize*mp2tMaxPackets)
r.ChangeState(config) err = r.ChangeState(config)
if err != nil {
return nil, err
}
switch r.config.Output { switch r.config.Output {
case file: case File:
r.outputFile, err = os.Create(r.config.OutputFileName) r.outputFile, err = os.Create(r.config.OutputFileName)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
switch r.config.Input { switch r.config.Input {
case file: case File:
r.inputFile, err = os.Open(r.config.InputFileName) r.inputFile, err = os.Open(r.config.InputFileName)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
switch r.config.InputCodec { switch r.config.InputCodec {
case h264: case H264:
r.Log(Info, "Using H264 parser!")
r.parser = parser.NewH264Parser() r.parser = parser.NewH264Parser()
case mjpeg: case Mjpeg:
r.parser = parser.NewMJPEGParser(mjpegParserInChanLen) r.parser = parser.NewMJPEGParser(mjpegParserInChanLen)
} }
switch r.config.Packetization { switch r.config.Packetization {
case none: case None:
r.parser.SetOutputChan(r.mjpegOutputChan) r.parser.SetOutputChan(r.mjpegOutputChan)
case mpegts: case Mpegts:
frameRateAsInt, _ := strconv.Atoi(r.config.FrameRate) frameRateAsInt, _ := strconv.Atoi(r.config.FrameRate)
r.generator = tsgenerator.NewTsGenerator(uint(frameRateAsInt)) r.generator = tsgenerator.NewTsGenerator(uint(frameRateAsInt))
r.parser.SetOutputChan(r.generator.GetNalInputChan()) r.parser.SetOutputChan(r.generator.GetNalInputChan())
@ -219,46 +224,65 @@ func (r *revidInst) ChangeState(config Config) error {
switch config.Output { switch config.Output {
case HttpOut: case HttpOut:
case File: case File:
case NothingDefine: case NothingDefined:
r.Log(Warning, "No output defined, defaulting to httpOut!") r.Log(Warning, "No output defined, defaulting to httpOut!")
config.Output = HttpOut config.Output = HttpOut
default: default:
return errors.New("Bad output type defined in config!") return errors.New("Bad output type defined in config!")
} }
if integer, err := strconv.Atoi(config.Width); integer < 0 || err != nil { if config.Width == "" {
return errors.New("Bad width defined in config!")
}
if integer, _ := strconv.Atoi(config.Width); integer == 0 {
r.Log(Warning, "No width defined, defaulting to 1280!") r.Log(Warning, "No width defined, defaulting to 1280!")
config.Width = defaultWidth config.Width = defaultWidth
} else {
if integer, err := strconv.Atoi(config.Width); integer < 0 || err != nil {
return errors.New("Bad width defined in config!")
}
} }
if integer, err := strconv.Atoi(config.Height); integer < 0 || err != nil {
return errors.New("Bad height defined in config!") if config.Height == "" {
}
if integer, _ := strconv.Atoi(config.Height); integer == 0 {
r.Log(Warning, "No height defined, defaulting to 720!") r.Log(Warning, "No height defined, defaulting to 720!")
config.Height = defaultHeight config.Height = defaultHeight
} else {
if integer, err := strconv.Atoi(config.Height); integer < 0 || err != nil {
return errors.New("Bad height defined in config!")
}
} }
if integer, err := strconv.Atoi(config.FrameRate); integer < 0 || err != nil {
return errors.New("Bad FrameRate defined in config!") if config.FrameRate == "" {
} r.Log(Warning, "No frame rate defined, defaulting to 25!")
if integer, _ := strconv.Atoi(config.FrameRate); integer == 0 {
r.Log(Warning, "No FrameRate defined, defaulting to 25!")
config.FrameRate = defaultFrameRate config.FrameRate = defaultFrameRate
} else {
if integer, err := strconv.Atoi(config.FrameRate); integer < 0 || err != nil {
return errors.New("Bad frame rate defined in config!")
}
} }
if integer, err := strconv.Atoi(config.Timeout); integer < 0 || err != nil {
return errors.New("Bad timeout defined in config!") if config.Timeout == "" {
r.Log(Warning, "No timeout defined, defaulting to 0!")
config.Timeout = defaultTimeout
} else {
if integer, err := strconv.Atoi(config.Timeout); integer < 0 || err != nil {
return errors.New("Bad timeout defined in config!")
}
} }
if integer, err := strconv.Atoi(config.IntraRefreshPeriod); integer < 0 || err != nil {
return errors.New("Bad intra refresh period defined in config!") if config.IntraRefreshPeriod == "" {
} r.Log(Warning, "No intra refresh defined, defaulting to 100!")
if integer, _ := strconv.Atoi(config.IntraRefreshPeriod); integer == 0 {
r.Log(Warning, "No intra refresh period defined, defaulting to 100!")
config.IntraRefreshPeriod = defaultIntraRefreshPeriod config.IntraRefreshPeriod = defaultIntraRefreshPeriod
} else {
if integer, err := strconv.Atoi(config.IntraRefreshPeriod); integer < 0 || err != nil {
return errors.New("Bad intra refresh defined in config!")
}
} }
if integer, err := strconv.Atoi(config.Quantization); integer <= 0 || integer > 51 || err != nil {
return errors.New("Bad quantization level defined in config!") if config.Quantization == "" {
r.Log(Warning, "No quantization defined, defaulting to 35!")
config.Quantization = defaultQuantization
} else {
if integer, err := strconv.Atoi(config.Quantization); integer <= 0 || integer > 51 || err != nil {
return errors.New("Bad quantization defined in config!")
}
} }
r.config = config r.config = config
return nil return nil
@ -290,13 +314,13 @@ func (r *revidInst) Start() {
r.Log(Info, "Starting Revid!") r.Log(Info, "Starting Revid!")
switch r.config.Input { switch r.config.Input {
case raspivid: case Raspivid:
r.Log(Info, "Starting raspivid!") r.Log(Info, "Starting raspivid!")
var codec string var codec string
switch r.config.InputCodec { switch r.config.InputCodec {
case h264: case H264:
codec = "H264" codec = "H264"
case mjpeg: case Mjpeg:
codec = "MJPEG" codec = "MJPEG"
} }
r.cmd = exec.Command("raspivid", r.cmd = exec.Command("raspivid",
@ -320,7 +344,7 @@ func (r *revidInst) Start() {
return return
} }
r.isRunning = true r.isRunning = true
case file: case File:
stats, err := r.inputFile.Stat() stats, err := r.inputFile.Stat()
if err != nil { if err != nil {
r.Log(Error, "Could not get input file stats!") r.Log(Error, "Could not get input file stats!")
@ -385,12 +409,12 @@ func (r *revidInst) packClips() {
if clip, err := r.ringBuffer.Get(); err != nil { if clip, err := r.ringBuffer.Get(); err != nil {
r.Log(Error, err.Error()) r.Log(Error, err.Error())
switch r.config.Packetization { switch r.config.Packetization {
case none: case None:
r.Log(Warning, "Clearing mjpeg chan!") r.Log(Warning, "Clearing mjpeg chan!")
for len(r.mjpegOutputChan) > 0 { for len(r.mjpegOutputChan) > 0 {
<-(r.mjpegOutputChan) <-(r.mjpegOutputChan)
} }
case mpegts: case Mpegts:
r.Log(Warning, "Clearing TS chan!") r.Log(Warning, "Clearing TS chan!")
for len(r.generator.GetTsOutputChan()) > 0 { for len(r.generator.GetTsOutputChan()) > 0 {
<-(r.generator.GetTsOutputChan()) <-(r.generator.GetTsOutputChan())
@ -400,13 +424,13 @@ func (r *revidInst) packClips() {
} else { } else {
for { for {
switch r.config.Packetization { switch r.config.Packetization {
case none: case None:
frame := <-r.mjpegOutputChan frame := <-r.mjpegOutputChan
upperBound := clipSize + len(frame) upperBound := clipSize + len(frame)
copy(clip[clipSize:upperBound], frame) copy(clip[clipSize:upperBound], frame)
packetCount++ packetCount++
clipSize += len(frame) clipSize += len(frame)
case mpegts: case Mpegts:
tsPacket := <-(r.generator.GetTsOutputChan()) tsPacket := <-(r.generator.GetTsOutputChan())
tsByteSlice, err := tsPacket.ToByteSlice() tsByteSlice, err := tsPacket.ToByteSlice()
if err != nil { if err != nil {
@ -453,9 +477,9 @@ func (r *revidInst) outputClips() {
r.Log(Debug, fmt.Sprintf("Delay is: %v\n", delay)) r.Log(Debug, fmt.Sprintf("Delay is: %v\n", delay))
r.Log(Debug, fmt.Sprintf("Ring buffer size: %v\n", r.ringBuffer.GetNoOfElements())) r.Log(Debug, fmt.Sprintf("Ring buffer size: %v\n", r.ringBuffer.GetNoOfElements()))
switch r.config.Output { switch r.config.Output {
case file: case File:
r.outputFile.Write(clip) r.outputFile.Write(clip)
case httpOut: case HttpOut:
bytes += len(clip) bytes += len(clip)
for err := r.sendClipToHTTP(clip, r.config.HttpAddress); err != nil; { for err := r.sendClipToHTTP(clip, r.config.HttpAddress); err != nil; {
r.Log(Error, err.Error()) r.Log(Error, err.Error())

View File

@ -33,17 +33,19 @@ import (
"time" "time"
) )
/*
// Test revidInst with a file input // Test revidInst with a file input
func TestFileInput(t *testing.T){ func TestFileInput(t *testing.T){
config := Config{ config := Config{
Input: file, Input: File,
InputFileName: "testInput.h264", InputFileName: "testInput.h264",
Output: file, Output: File,
OutputFileName: "output/TestFileAsInput.ts", OutputFileName: "output/TestFileAsInput.ts",
} }
revidInst, err := NewRevidInstance(config) revidInst, err := NewRevidInstance(config)
if err != nil { if err != nil {
t.Errorf("Should not have got error!") t.Errorf("Should not have got error!: %v\n", err.Error())
return
} }
revidInst.Start() revidInst.Start()
time.Sleep(100*time.Second) time.Sleep(100*time.Second)
@ -58,36 +60,37 @@ func TestRaspividH264Input(t *testing.T){
OutputFileName: "output/TestRaspividOutput.ts", OutputFileName: "output/TestRaspividOutput.ts",
Width: "1280", Width: "1280",
Height: "720", Height: "720",
Bitrate: "1000000",
FrameRate: "25", FrameRate: "25",
} }
revidInst, err := NewRevidInstance(config) revidInst, err := NewRevidInstance(config)
if err != nil { if err != nil {
t.Errorf("Should not have got an error!") t.Errorf("Should not have got an error!")
return
} }
revidInst.Start() revidInst.Start()
time.Sleep(100*time.Second) time.Sleep(100*time.Second)
revidInst.Stop() revidInst.Stop()
} }
*/
// Test revidInst with a raspivid mjpeg input // Test revidInst with a raspivid mjpeg input
func TestRaspividMJPEGInput(t *testing.T){ func TestRaspividMJPEGInput(t *testing.T){
config := Config{ config := Config{
Input: Raspivid, Input: Raspivid,
InputCodec: mjpeg, InputCodec: Mjpeg,
Output: File, Output: File,
OutputFileName: "output/TestRaspividMjpegOutput.mjpeg", OutputFileName: "output/TestRaspividMjpegOutput.mjpeg",
Width: "1280", Width: "1280",
Height: "720", Height: "720",
Bitrate: "0",
Quantization: "35", Quantization: "35",
FrameRate: "25", FrameRate: "25",
} }
revidInst, err := NewRevidInstance(config) revidInst, err := NewRevidInstance(config)
if err != nil { if err != nil {
t.Errorf("Should not of have got an error!") t.Errorf("Should not of have got an error!")
return
} }
revidInst.Start() revidInst.Start()
time.Sleep(100*time.Second) time.Sleep(10*time.Second)
revidInst.Stop() revidInst.Stop()
} }