codec/mjpeg/lex & lex_test.go: modified Lex to work with thumbnailed JPEG images and fixed Lex tests.

This commit is contained in:
Saxon Nelson-Milton 2021-01-16 16:22:56 +10:30
parent 1179ab4293
commit 16d7a16762
4 changed files with 59 additions and 18 deletions

View File

@ -3,10 +3,12 @@ NAME
lex.go
DESCRIPTION
lex.go provides a lexer to extract separate JPEG images from a MJPEG stream.
lex.go provides a lexer to extract separate JPEG images from a JPEG stream.
This could either be a series of descrete JPEG images, or an MJPEG stream.
AUTHOR
Dan Kortschak <dan@ausocean.org>
Saxon Nelson-Milton <saxon@ausocean.org>
LICENSE
lex.go is Copyright (C) 2017 the Australian Ocean Lab (AusOcean)
@ -25,8 +27,6 @@ LICENSE
along with revid in gpl.txt. If not, see http://www.gnu.org/licenses.
*/
// lex.go provides a lexer to extract separate JPEG images from a MJPEG stream.
package mjpeg
import (
@ -35,15 +35,19 @@ import (
"fmt"
"io"
"time"
"bitbucket.org/ausocean/utils/logger"
)
var Log logger.LoggerIF
var noDelay = make(chan time.Time)
func init() {
close(noDelay)
}
// Lex parses MJPEG frames read from src into separate writes to dst with
// Lex parses JPEG frames read from src into separate writes to dst with
// successive writes being performed not earlier than the specified delay.
func Lex(dst io.Writer, src io.Reader, delay time.Duration) error {
var tick <-chan time.Time
@ -65,9 +69,13 @@ func Lex(dst io.Writer, src io.Reader, delay time.Duration) error {
if err != nil {
return err
}
if !bytes.Equal(buf, []byte{0xff, 0xd8}) {
return fmt.Errorf("parser: not MJPEG frame start: %#v", buf)
return fmt.Errorf("parser: not JPEG frame start: %#v", buf)
}
nImg := 1
var last byte
for {
b, err := r.ReadByte()
@ -77,16 +85,28 @@ func Lex(dst io.Writer, src io.Reader, delay time.Duration) error {
}
return err
}
buf = append(buf, b)
if last == 0xff && b == 0xd8 {
nImg++
}
if last == 0xff && b == 0xd9 {
nImg--
}
if nImg == 0 {
<-tick
Log.Debug("writing buf","len(buf)",len(buf))
_, err = dst.Write(buf)
if err != nil {
return err
}
break
}
last = b
}
<-tick
_, err = dst.Write(buf)
if err != nil {
return err
}
}
}

View File

@ -30,10 +30,17 @@ LICENSE
package mjpeg
import (
"bytes"
"fmt"
"io"
"reflect"
"testing"
"time"
"bitbucket.org/ausocean/utils/logger"
)
var mjpegTests = []struct {
var jpegTests = []struct {
name string
input []byte
delay time.Duration
@ -42,18 +49,21 @@ var mjpegTests = []struct {
}{
{
name: "empty",
err: io.ErrUnexpectedEOF,
},
{
name: "null",
input: []byte{0xff, 0xd8, 0xff, 0xd9},
delay: 0,
want: [][]byte{{0xff, 0xd8, 0xff, 0xd9}},
err: io.ErrUnexpectedEOF,
},
{
name: "null delayed",
input: []byte{0xff, 0xd8, 0xff, 0xd9},
delay: time.Millisecond,
want: [][]byte{{0xff, 0xd8, 0xff, 0xd9}},
err: io.ErrUnexpectedEOF,
},
{
name: "full",
@ -72,6 +82,7 @@ var mjpegTests = []struct {
{0xff, 0xd8, 'l', 'e', 'n', 'g', 't', 'h', 0xff, 0xd9},
{0xff, 0xd8, 's', 'p', 'r', 'e', 'a', 'd', 0xff, 0xd9},
},
err: io.ErrUnexpectedEOF,
},
{
name: "full delayed",
@ -90,15 +101,15 @@ var mjpegTests = []struct {
{0xff, 0xd8, 'l', 'e', 'n', 'g', 't', 'h', 0xff, 0xd9},
{0xff, 0xd8, 's', 'p', 'r', 'e', 'a', 'd', 0xff, 0xd9},
},
err: io.ErrUnexpectedEOF,
},
}
// FIXME this needs to be adapted
/*
func Lex(t *testing.T) {
for _, test := range mjpegTests {
func TestLex(t *testing.T) {
Log = (*logger.TestLogger)(t)
for _, test := range jpegTests {
var buf chunkEncoder
err := MJPEG(&buf, bytes.NewReader(test.input), test.delay)
err := Lex(&buf, bytes.NewReader(test.input), test.delay)
if fmt.Sprint(err) != fmt.Sprint(test.err) {
t.Errorf("unexpected error for %q: got:%v want:%v", test.name, err, test.err)
}
@ -111,4 +122,12 @@ func Lex(t *testing.T) {
}
}
}
*/
type chunkEncoder [][]byte
func (e *chunkEncoder) Write(b []byte) (int, error) {
*e = append(*e, b)
return len(b), nil
}
func (*chunkEncoder) Stream() <-chan []byte { panic("INVALID USE") }

2
go.mod
View File

@ -4,7 +4,7 @@ go 1.13
require (
bitbucket.org/ausocean/iot v1.3.0
bitbucket.org/ausocean/utils v1.2.15
bitbucket.org/ausocean/utils v1.2.17
github.com/Comcast/gots v0.0.0-20190305015453-8d56e473f0f7
github.com/go-audio/audio v0.0.0-20181013203223-7b2a6ca21480
github.com/go-audio/wav v0.0.0-20181013172942-de841e69b884

2
go.sum
View File

@ -6,6 +6,8 @@ bitbucket.org/ausocean/utils v1.2.14 h1:v5eBYavkEqKOBCppR6P451eT9UT/CQReMsOZZBUP
bitbucket.org/ausocean/utils v1.2.14/go.mod h1:uXzX9z3PLemyURTMWRhVI8uLhPX4uuvaaO85v2hcob8=
bitbucket.org/ausocean/utils v1.2.15 h1:Pz99ZfobdhACTtU6oj9BTyBcNSQulLvPT7wq4P343Es=
bitbucket.org/ausocean/utils v1.2.15/go.mod h1:uXzX9z3PLemyURTMWRhVI8uLhPX4uuvaaO85v2hcob8=
bitbucket.org/ausocean/utils v1.2.17 h1:6ZqXvxRXHHL18s2kn22E2/AORNn2WsgQXcEnctWwvrk=
bitbucket.org/ausocean/utils v1.2.17/go.mod h1:uoIRyy4jwH0/9b/t9tfPuV9Vl14AONeILw9KimUISYg=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Comcast/gots v0.0.0-20190305015453-8d56e473f0f7 h1:LdOc9B9Bj6LEsKiXShkLA3/kpxXb6LJpH+ekU2krbzw=