/* NAME Parser.go DESCRIPTION See Readme.md AUTHOR Saxon Nelson-Milton LICENSE RtpToTsConverter.go is Copyright (C) 2017 the Australian Ocean Lab (AusOcean) It is free software: you can redistribute it and/or modify them under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. It is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with revid in gpl.txt. If not, see [GNU licenses](http://www.gnu.org/licenses). */ package parser import ( //"bitbucket.org/ausocean/av/itut" "../itut" "log" "sync" _"time" ) // h264 consts const ( acceptedLength = 1000 ) var ( Info *log.Logger mutex *sync.Mutex ) type Parser interface { Stop() Start() GetInputChan() chan byte GetOutputChan() chan []byte SetOutputChan(achan chan []byte) } type h264Parser struct { inputBuffer []byte isParsing bool parserOutputChanRef chan []byte userOutputChanRef chan []byte inputChan chan byte } func NewH264Parser() (p *h264Parser) { p = new(h264Parser) p.isParsing = true p.inputChan = make(chan byte, 10000) return } func (p* h264Parser)Stop(){ p.isParsing = false } func (p *h264Parser)Start(){ go p.parse() } func (p *h264Parser)GetInputChan() chan byte { return p.inputChan } func (p *h264Parser)GetOutputChan() chan []byte { return p.userOutputChanRef } func (p *h264Parser)SetOutputChan(aChan chan []byte){ p.parserOutputChanRef = aChan p.userOutputChanRef = aChan } func (p *h264Parser)parse() { outputBuffer := make([]byte, 0, 10000) searchingForEnd := false for p.isParsing { aByte := <-p.inputChan outputBuffer = append(outputBuffer, aByte) for i:=1; aByte == 0x00 && i != 4; i++ { aByte = <-p.inputChan outputBuffer = append(outputBuffer, aByte) if ( aByte == 0x01 && i == 2 ) || ( aByte == 0x01 && i == 3 ) { if searchingForEnd { output := append(append(itut.StartCode1(),itut.AUD()...),outputBuffer[:len(outputBuffer)-(i+1)]...) p.parserOutputChanRef<-output outputBuffer = outputBuffer[len(outputBuffer)-1-i:] searchingForEnd = false } aByte = <-p.inputChan outputBuffer = append(outputBuffer, aByte) if nalType := aByte & 0x1F; nalType == 1 || nalType == 5 { searchingForEnd = true } } } } } type mjpegParser struct { inputBuffer []byte isParsing bool parserOutputChanRef chan []byte userOutputChanRef chan []byte inputChan chan byte } func NewMJPEGParser(inputChanLen int) (p *mjpegParser){ p = new(mjpegParser) p.isParsing = true p.inputChan = make(chan byte, inputChanLen ) return } func (p *mjpegParser)Stop(){ p.isParsing = false } func (p *mjpegParser)Start(){ go p.parse() } func (p *mjpegParser)GetInputChan() chan byte { return p.inputChan } func (p *mjpegParser)GetOutputChan() chan []byte { return p.userOutputChanRef } func (p *mjpegParser)SetOutputChan(aChan chan []byte){ p.parserOutputChanRef = aChan p.userOutputChanRef = aChan } func (p *mjpegParser)parse() { var outputBuffer []byte for p.isParsing { aByte := <-p.inputChan outputBuffer = append(outputBuffer, aByte) if aByte == 0xFF && len(outputBuffer) != 0 { aByte := <-p.inputChan outputBuffer = append(outputBuffer, aByte) if aByte == 0xD8 { p.parserOutputChanRef<-outputBuffer[:len(outputBuffer)-2] outputBuffer = outputBuffer[len(outputBuffer)-2:] } } } }