diff --git a/parser/h264.go b/parser/h264.go index 630c6ee2..86ecd030 100644 --- a/parser/h264.go +++ b/parser/h264.go @@ -130,7 +130,7 @@ func (p *H264) parse() { return } outputBuffer = append(outputBuffer, aByte) - if nalType := aByte & 0x1F; nalType == 1 || nalType == 5 || nalType == 8 { + if nalType := aByte & 0x1F; nalType == 1 || nalType == 5 || nalType == 8 || nalType == 7 { searchingForEnd = true } } diff --git a/parser/parser_test.go b/parser/parser_test.go index c23e85e6..066dbf11 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -1,53 +1,127 @@ +/* +NAME + parser_test.go + +DESCRIPTION + See Readme.md + +AUTHOR + Saxon Nelson-Milton + +LICENSE + parser_test.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 http://www.gnu.org/licenses. +*/ + package parser import ( "fmt" + "io/ioutil" + "log" "os" "strconv" "testing" ) const ( - testInputFileName = "testInput/testInput.avi" + mjpegInputFileName = "testInput/testInput.avi" + h264fName = "../../test/test-data/av/input/betterInput.h264" + nOfFrames = 4 + outChanSize = 100 ) +func TestH264Parser(t *testing.T) { + log.SetOutput(os.Stderr) + log.Println("Opening input file!") + inputFile, err := os.Open(h264fName) + if err != nil { + t.Errorf("Should not have got error opening file!") + return + } + + log.Println("Reading data from file!") + data, err := ioutil.ReadAll(inputFile) + if err != nil { + t.Errorf("Should not have got read error!") + return + } + + // Create 'parser' and start it up + log.Println("Creating parser!") + parser := NewH264Parser() + parser.SetOutputChan(make(chan []byte, outChanSize)) + parser.Start() + + for i, n := 0, 0; n <= nOfFrames; i++ { + select { + case parser.InputChan() <- data[i]: + case frame := <-parser.OutputChan(): + path := fmt.Sprintf("testOutput/" + strconv.Itoa(n) + "h264_frame") + out, err := os.Create(path) + if err != nil { + t.Errorf("Unexpected error creating %q: %v", path, err) + return + } + out.Write(frame) + out.Close() + n++ + default: + } + } +} + +/* func TestMJPEGParser(t *testing.T) { - fmt.Println("Opening input file!") + log.Println("Opening input file!") // Open the input file inputFile, err := os.Open(testInputFileName) if err != nil { t.Errorf("Should not have got error opening file!") } - fmt.Println("Getting file stats!") + log.Println("Getting file stats!") stats, err := inputFile.Stat() if err != nil { t.Errorf("Could not get input file stats!") return } - fmt.Println("Creating space for file data!") + log.Println("Creating space for file data!") data := make([]byte, stats.Size()) _, err = inputFile.Read(data) if err != nil { t.Errorf("Should not have got read error!") return } - fmt.Println("Creating parser!") + log.Println("Creating parser!") parser := NewMJPEGParser(len(data) + 1) parser.SetOutputChan(make(chan []byte, 10000)) parser.Start() - fmt.Printf("len(data): %v\n", len(data)) + log.Printf("len(data): %v\n", len(data)) for i := range data { parser.GetInputChan() <- data[i] } - fmt.Println("Writing jpegs to files!") + log.Println("Writing jpegs to files!") for i := 0; len(parser.GetOutputChan()) > 0; i++ { // Open a new output file - outputFile, err := os.Create("testOutput/image" + strconv.Itoa(i) + ".jpeg") + out, err := os.Create("testOutput/image" + strconv.Itoa(i) + ".jpeg") if err != nil { t.Errorf("Should not have got error creating output file!") return } - outputFile.Write(<-parser.GetOutputChan()) - outputFile.Close() + out.Write(<-parser.GetOutputChan()) + out.Close() } } +*/ diff --git a/revid/cmd/h264-file-to-flv-rtmp/main b/revid/cmd/h264-file-to-flv-rtmp/main new file mode 100755 index 00000000..b9e7fd78 Binary files /dev/null and b/revid/cmd/h264-file-to-flv-rtmp/main differ diff --git a/revid/cmd/h264-file-to-flv-rtmp/main.go b/revid/cmd/h264-file-to-flv-rtmp/main.go new file mode 100644 index 00000000..082bd549 --- /dev/null +++ b/revid/cmd/h264-file-to-flv-rtmp/main.go @@ -0,0 +1,71 @@ +/* +NAME + main.go + +DESCRIPTION + See Readme.md + +AUTHOR + Saxon Nelson-Milton + +LICENSE + main.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 main + +import ( + "flag" + "log" + "time" + + "bitbucket.org/ausocean/av/revid" +) + +const ( + inputFile = "../../../../test/test-data/av/input/betterInput.h264" + frameRate = "25" + runDuration = 120 * time.Second +) + +// Test h264 inputfile to flv format into rtmp using librtmp c wrapper +func main() { + // Get the rtmp url from a cmd flag + rtmpUrlPtr := flag.String("rtmpUrl", "", "The rtmp url you would like to stream to.") + flag.Parse() + if *rtmpUrlPtr == "" { + log.Println("No RTMP url passed!") + return + } + + config := revid.Config{ + Input: revid.File, + InputFileName: inputFile, + InputCodec: revid.H264, + Output: revid.Rtmp, + RtmpMethod: revid.LibRtmp, + RtmpUrl: *rtmpUrlPtr, + Packetization: revid.Flv, + } + revidInst, err := revid.New(config, nil) + if err != nil { + log.Printf("Should not of have got an error!: %v\n", err.Error()) + return + } + revidInst.Start() + time.Sleep(runDuration) + revidInst.Stop() +} diff --git a/revid/revid_test.go b/revid/revid_test.go index 7c2e9637..79f07fc4 100644 --- a/revid/revid_test.go +++ b/revid/revid_test.go @@ -96,31 +96,6 @@ func TestRaspividMJPEGInput(t *testing.T){ -// Test revidInst with rtmp output -func TestRtmpOutput(t *testing.T){ - config := Config{ - Input: File, - InputFileName: "testInput.h264", - InputCodec: H264, - Output: Rtmp, - RtmpUrl: "rtmp://a.rtmp.youtube.com/live2/w44c-mkuu-aezg-ceb1", - Width: "1280", - Height: "720", - FrameRate: "25", - Packetization: None, - FramesPerClip: 1, - } - revidInst, err := NewRevidInstance(config) - if err != nil { - t.Errorf("Should not of have got an error!: %v\n", err.Error()) - return - } - revidInst.Start() - time.Sleep(120*time.Second) - revidInst.Stop() -} - - // Test h264 inputfile to flv output files func TestFlvOutputFile(t *testing.T) { diff --git a/rtmp/rtmp.go b/rtmp/rtmp.go index fac20d1a..77bf533b 100644 --- a/rtmp/rtmp.go +++ b/rtmp/rtmp.go @@ -30,7 +30,7 @@ package rtmp /* #cgo CFLAGS: -I/usr/local/include/librtmp -#cgo LDFLAGS: -lrtmp -lz +#cgo LDFLAGS: -lrtmp -lz -Wl,-rpath=/usr/local/lib #include #include