78 lines
2.2 KiB
Go
78 lines
2.2 KiB
Go
package device
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"io"
|
|
"net"
|
|
"testing"
|
|
)
|
|
|
|
type streamTestWriter struct{ bytes.Buffer }
|
|
|
|
func (*streamTestWriter) Close() error { return nil }
|
|
|
|
func TestPumpH264ForwardsConfigAndFrames(t *testing.T) {
|
|
// The configuration payload deliberately resembles an invalid packet header.
|
|
// Skipping it would corrupt alignment and lose all following video frames.
|
|
config := []byte{0, 0, 0, 1, 0x67, 0x64, 0, 0x28, 0, 0, 0, 1, 0x68, 0xeb}
|
|
keyframe := []byte{0, 0, 0, 1, 0x65, 1, 2, 3}
|
|
next := []byte{0, 0, 0, 1, 0x41, 4, 5}
|
|
var wire bytes.Buffer
|
|
wire.WriteString("h264")
|
|
// Initial session and later rotation both use standalone 12-byte headers.
|
|
session := func(width, height uint32) {
|
|
_ = binary.Write(&wire, binary.BigEndian, uint32(1<<31))
|
|
_ = binary.Write(&wire, binary.BigEndian, width)
|
|
_ = binary.Write(&wire, binary.BigEndian, height)
|
|
}
|
|
session(576, 1280)
|
|
for i, payload := range [][]byte{config, keyframe, next} {
|
|
if i == 2 {
|
|
session(1280, 576)
|
|
}
|
|
var flags uint64
|
|
if i == 0 {
|
|
flags = 1 << 62
|
|
}
|
|
if i == 1 {
|
|
flags = 1 << 61
|
|
}
|
|
_ = binary.Write(&wire, binary.BigEndian, flags)
|
|
_ = binary.Write(&wire, binary.BigEndian, uint32(len(payload)))
|
|
wire.Write(payload)
|
|
}
|
|
input, peer := net.Pipe()
|
|
defer input.Close()
|
|
go func() { _, _ = peer.Write(wire.Bytes()); _ = peer.Close() }()
|
|
if err := readVideoCodec(input); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
output := &streamTestWriter{}
|
|
err := (&previewStream{}).pumpH264(input, output, make(chan struct{}))
|
|
if err != io.EOF {
|
|
t.Fatalf("unexpected end: %v", err)
|
|
}
|
|
want := bytes.Join([][]byte{config, keyframe, next}, nil)
|
|
if !bytes.Equal(output.Bytes(), want) {
|
|
t.Fatalf("lost codec config or packet alignment: got %x want %x", output.Bytes(), want)
|
|
}
|
|
}
|
|
|
|
func TestPumpH264RejectsInvalidLength(t *testing.T) {
|
|
for _, size := range []uint32{0, 16*1024*1024 + 1} {
|
|
input, peer := net.Pipe()
|
|
go func() {
|
|
defer peer.Close()
|
|
hdr := make([]byte, 12)
|
|
binary.BigEndian.PutUint32(hdr[8:], size)
|
|
_, _ = peer.Write(hdr)
|
|
}()
|
|
err := (&previewStream{}).pumpH264(input, &streamTestWriter{}, make(chan struct{}))
|
|
input.Close()
|
|
if err == nil || err == io.EOF {
|
|
t.Fatalf("length %d was not rejected: %v", size, err)
|
|
}
|
|
}
|
|
}
|