mirror of https://bitbucket.org/ausocean/av.git
Updating remote
This commit is contained in:
parent
00a6bd8212
commit
dd05c13110
|
@ -30,17 +30,24 @@ package h264
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bitbucket.org/ausocean/av/itut"
|
"bitbucket.org/ausocean/av/itut"
|
||||||
"reflect"
|
"log"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
acceptedLength = 1000
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
Info *log.Logger
|
||||||
|
mutex *sync.Mutex
|
||||||
)
|
)
|
||||||
|
|
||||||
type H264Parser struct {
|
type H264Parser struct {
|
||||||
inputBuffer []byte
|
inputBuffer []byte
|
||||||
isParsing bool
|
isParsing bool
|
||||||
OutputChan chan<- []byte
|
OutputChan chan<- []byte
|
||||||
}
|
InputByteChan chan byte
|
||||||
|
|
||||||
func (p* H264Parser)SendInputData(someData []byte){
|
|
||||||
p.inputBuffer = append(p.inputBuffer, someData...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p* H264Parser)Stop(){
|
func (p* H264Parser)Stop(){
|
||||||
|
@ -49,30 +56,58 @@ func (p* H264Parser)Stop(){
|
||||||
|
|
||||||
func (p* H264Parser)Parse() {
|
func (p* H264Parser)Parse() {
|
||||||
p.isParsing = true
|
p.isParsing = true
|
||||||
buffer := p.inputBuffer
|
outputBuffer := []byte{}
|
||||||
|
searchingForEnd := false
|
||||||
|
p.InputByteChan = make(chan byte, 10000)
|
||||||
for p.isParsing {
|
for p.isParsing {
|
||||||
for i := 0; len(buffer) > 10; i++{
|
aByte := <-p.InputByteChan
|
||||||
var start bool
|
|
||||||
i, start = func() (int,bool) {
|
outputBuffer = append(outputBuffer, aByte)
|
||||||
switch{
|
for i:=1; aByte == 0x00 && i != 4; i++ {
|
||||||
case reflect.DeepEqual(buffer[i:i+3],itut.StartCode1()):
|
aByte = <-p.InputByteChan
|
||||||
return i+3, true
|
outputBuffer = append(outputBuffer, aByte)
|
||||||
case reflect.DeepEqual(buffer[i:i+4],itut.StartCode2()):
|
if ( aByte == 0x01 && i == 2 ) || ( aByte == 0x01 && i == 3 ) {
|
||||||
return i+4, true
|
if searchingForEnd {
|
||||||
|
outputBuffer = outputBuffer[:len(outputBuffer)-(i+1)]
|
||||||
|
p.OutputChan<-append(append(itut.StartCode1(),itut.AUD()...),outputBuffer...)
|
||||||
|
outputBuffer = []byte{}
|
||||||
|
searchingForEnd = false
|
||||||
}
|
}
|
||||||
return i, false
|
aByte = <-p.InputByteChan
|
||||||
}()
|
outputBuffer = append(outputBuffer, aByte)
|
||||||
if nalType := buffer[i] & 0x1F; start && ( nalType == 1 || nalType == 5) {
|
if nalType := aByte & 0x1F; nalType == 1 || nalType == 5 {
|
||||||
for ; i < len(buffer) && !(i+3 < len(buffer) && ( reflect.DeepEqual(buffer[i:i+3],itut.StartCode1()) ||
|
searchingForEnd = true
|
||||||
reflect.DeepEqual(buffer[i:i+4],itut.StartCode2()))); i++ {}
|
|
||||||
p.OutputChan<-append(append(itut.StartCode1(),itut.AUD()...),buffer[:i]...)
|
|
||||||
buffer = buffer[i:]
|
|
||||||
i=0
|
|
||||||
}
|
|
||||||
if i >= len(buffer) {
|
|
||||||
buffer = []byte{}
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
for p.isParsing {
|
||||||
|
aByte := <-p.InputByteChan
|
||||||
|
outputBuffer = append(outputBuffer, aByte)
|
||||||
|
for i:=1; aByte == 0x00 && i != 4; i++ {
|
||||||
|
aByte = <-p.InputByteChan
|
||||||
|
outputbuffer = append(outputBuffer, aByte)
|
||||||
|
if ( aByte == 0x01 && i == 2 ) || ( aByte == 0x01 && i == 3 ) {
|
||||||
|
aByte = <-p.InputByteChan
|
||||||
|
outputBuffer = append(outputBuffer, aByte)
|
||||||
|
if nalType := aByte & 0x1F; nalType == 1 || nalType == 5 {
|
||||||
|
for {
|
||||||
|
aByte = <-p.InputByteChan
|
||||||
|
outputBuffer = append(outputBuffer,aByte)
|
||||||
|
for i := 1; aByte == 0x00; i++ {
|
||||||
|
aByte = <-p.InputByteChan
|
||||||
|
outputbuffer = append(outputBuffer, aByte)
|
||||||
|
if ( aByte == 0x01 && i == 2 ) || ( aByte == 0x01 && i == 3 ) {
|
||||||
|
outputBuffer = outputBuffer[:len(outputBuffer)-(i+1)]
|
||||||
|
outputChan<-append(append(itut.StartCode1(),itut.AUD()...),outputBuffer...)
|
||||||
|
outputBuffer = []byte{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
|
@ -30,4 +30,4 @@ package itut
|
||||||
|
|
||||||
func StartCode1() []byte { return []byte{0x00, 0x00, 0x01} }
|
func StartCode1() []byte { return []byte{0x00, 0x00, 0x01} }
|
||||||
func StartCode2() []byte { return []byte{0x00, 0x00, 0x00, 0x01} }
|
func StartCode2() []byte { return []byte{0x00, 0x00, 0x00, 0x01} }
|
||||||
func AUD() []byte { return []byte{0x09, 0x10} }
|
func AUD() []byte { return []byte{0x09, 0xF0} }
|
||||||
|
|
|
@ -43,6 +43,7 @@ import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
"io"
|
||||||
|
|
||||||
"bitbucket.org/ausocean/av/h264"
|
"bitbucket.org/ausocean/av/h264"
|
||||||
"bitbucket.org/ausocean/av/tsgenerator"
|
"bitbucket.org/ausocean/av/tsgenerator"
|
||||||
|
@ -68,6 +69,7 @@ const (
|
||||||
defaultRaspividCmd = "raspivid -o -"
|
defaultRaspividCmd = "raspivid -o -"
|
||||||
framesPerSec = 25
|
framesPerSec = 25
|
||||||
packetsPerFrame = 7
|
packetsPerFrame = 7
|
||||||
|
h264BufferSize = 500000
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -83,9 +85,9 @@ type Config struct {
|
||||||
InputCmd string
|
InputCmd string
|
||||||
Output uint8
|
Output uint8
|
||||||
OutputFileName string
|
OutputFileName string
|
||||||
|
InputFileName string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type RevidInst interface {
|
type RevidInst interface {
|
||||||
Start()
|
Start()
|
||||||
Stop()
|
Stop()
|
||||||
|
@ -122,6 +124,13 @@ func NewRevidInstance(config Config) (r *revidInst, err error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
switch r.config.Input {
|
||||||
|
case file:
|
||||||
|
r.inputFile, err = os.Open(r.config.InputFileName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,11 +154,13 @@ func (r *revidInst) input() {
|
||||||
generator := tsgenerator.NewTsGenerator(framesPerSec)
|
generator := tsgenerator.NewTsGenerator(framesPerSec)
|
||||||
go generator.Generate()
|
go generator.Generate()
|
||||||
h264Parser := h264.H264Parser{OutputChan: generator.NalInputChan}
|
h264Parser := h264.H264Parser{OutputChan: generator.NalInputChan}
|
||||||
|
// TODO: Need to create constructor for parser otherwise I'm going to break
|
||||||
|
// something eventuallyl
|
||||||
go h264Parser.Parse()
|
go h264Parser.Parse()
|
||||||
var inputReader *bufio.Reader
|
var inputReader *bufio.Reader
|
||||||
switch r.config.Input {
|
switch r.config.Input {
|
||||||
case raspivid:
|
case raspivid:
|
||||||
cmd := exec.Command("raspivid", "-o -")
|
cmd := exec.Command("raspivid", "-o", "-", "-n", "-t", "0")
|
||||||
stdout, _ := cmd.StdoutPipe()
|
stdout, _ := cmd.StdoutPipe()
|
||||||
err := cmd.Start()
|
err := cmd.Start()
|
||||||
inputReader = bufio.NewReader(stdout)
|
inputReader = bufio.NewReader(stdout)
|
||||||
|
@ -157,6 +168,9 @@ func (r *revidInst) input() {
|
||||||
r.Error.Println(err.Error())
|
r.Error.Println(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
case file:
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
r.Error.Println("Input not valid!")
|
r.Error.Println("Input not valid!")
|
||||||
}
|
}
|
||||||
|
@ -176,11 +190,36 @@ func (r *revidInst) input() {
|
||||||
donePSI := false
|
donePSI := false
|
||||||
ii := 0
|
ii := 0
|
||||||
for r.isRunning {
|
for r.isRunning {
|
||||||
h264Data, err := ioutil.ReadAll(inputReader)
|
fmt.Println("reading")
|
||||||
|
var h264Data []byte
|
||||||
|
switch(r.config.Input){
|
||||||
|
case raspivid:
|
||||||
|
go func(){
|
||||||
|
for {
|
||||||
|
h264Data = make([]byte, 1)
|
||||||
|
io.ReadFull(inputReader, h264Data)
|
||||||
|
h264Parser.InputByteChan<-h264Data[0]
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
case file:
|
||||||
|
stats, err := r.inputFile.Stat()
|
||||||
|
if err != nil {
|
||||||
|
panic("Could not get file stats!")
|
||||||
|
}
|
||||||
|
h264Data = make([]byte, stats.Size())
|
||||||
|
_, err = r.inputFile.Read(h264Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.Error.Println(err.Error())
|
r.Error.Println(err.Error())
|
||||||
}
|
}
|
||||||
h264Parser.SendInputData(h264Data)
|
fmt.Println("about to start sending data")
|
||||||
|
for i := range h264Data {
|
||||||
|
fmt.Printf("i: %v\n", i)
|
||||||
|
h264Parser.InputByteChan<-h264Data[i]
|
||||||
|
}
|
||||||
|
fmt.Println("all data sent")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if clip, err := r.ringBuffer.Get(); err != nil {
|
if clip, err := r.ringBuffer.Get(); err != nil {
|
||||||
r.Error.Println(err.Error())
|
r.Error.Println(err.Error())
|
||||||
return
|
return
|
||||||
|
@ -196,7 +235,9 @@ func (r *revidInst) input() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
byteSlice,err := (<-generator.TsChan).ToByteSlice()
|
fmt.Println("getting ts packet")
|
||||||
|
tsPacket := <-generator.TsChan
|
||||||
|
byteSlice, err := tsPacket.ToByteSlice()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.Error.Println(err.Error())
|
r.Error.Println(err.Error())
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,13 +33,34 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Testing with file input
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
func TestFileInput(t *testing.T){
|
||||||
|
config := Config{
|
||||||
|
Input: file,
|
||||||
|
InputFileName: "testInput.h264",
|
||||||
|
Output: file,
|
||||||
|
OutputFileName: "output/TestFileAsInput.ts",
|
||||||
|
}
|
||||||
|
revidInst, err := NewRevidInstance(config)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Should not have got error!")
|
||||||
|
}
|
||||||
|
revidInst.Start()
|
||||||
|
time.Sleep(100*time.Second)
|
||||||
|
revidInst.Stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Testing use with raspivid
|
Testing use with raspivid
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
func TestRaspividInput(t *testing.T){
|
func TestRaspividInput(t *testing.T){
|
||||||
config := Config{
|
config := Config{
|
||||||
Input: raspivid,
|
Input: raspivid,
|
||||||
InputCmd: "raspivid",
|
|
||||||
Output: file,
|
Output: file,
|
||||||
OutputFileName: "output/TestRaspividOutput.ts",
|
OutputFileName: "output/TestRaspividOutput.ts",
|
||||||
}
|
}
|
||||||
|
@ -48,6 +69,10 @@ func TestRaspividInput(t *testing.T){
|
||||||
t.Errorf("Should not have got an error!")
|
t.Errorf("Should not have got an error!")
|
||||||
}
|
}
|
||||||
revidInst.Start()
|
revidInst.Start()
|
||||||
time.Sleep(5*time.Second)
|
time.Sleep(100*time.Second)
|
||||||
revidInst.Stop()
|
revidInst.Stop()
|
||||||
}
|
}
|
||||||
|
* */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue