package protocol import ( "bytes" "testing" ) // TestWriteReadVideoPacket verifies the full video packet round-trip through // WritePacket/ReadPacket, including the little-endian float32s in the image // header and the exact byte layout (Header + ImageHeader + payload). func TestWriteReadVideoPacket(t *testing.T) { img := DefaultBT709Full() img.ColorMatrix[0] = 0.12345 img.ColorRangeMax[2] = 0.9999 h := Header{Type: VideoType, Timestamp: 1_700_000_000, Size: 5} wire, err := WritePacket(h, &img, nil, []byte("hello")) if err != nil { t.Fatalf("WritePacket: %v", err) } gotH, gotImg, gotWave, payload, err := ReadPacket(bytes.NewReader(wire)) if err != nil { t.Fatalf("ReadPacket: %v", err) } if gotH != h { t.Errorf("header mismatch: got %+v want %+v", gotH, h) } if gotImg == nil || gotWave != nil { t.Fatalf("expected image header and no wave header") } if *gotImg != img { t.Errorf("image header mismatch:\n got %+v\nwant %+v", *gotImg, img) } if string(payload) != "hello" { t.Errorf("payload mismatch: got %q", payload) } } // TestVideoPacketWireSize locks the on-wire size of a video packet to the // reference layout: 16-byte Header + 80-byte ImageHeader + payload. func TestVideoPacketWireSize(t *testing.T) { const payload = 10 ih := DefaultBT709Full() h := Header{Type: VideoType, Size: payload} wire, err := WritePacket(h, &ih, nil, make([]byte, payload)) if err != nil { t.Fatalf("WritePacket: %v", err) } if len(wire) != headerSize+imageHeaderSize+payload { t.Errorf("wire size = %d, want %d", len(wire), headerSize+imageHeaderSize+payload) } } // TestWriteReadAudioPacket round-trips a WAVE packet and checks that the // WaveHeader fields arrive intact. func TestWriteReadAudioPacket(t *testing.T) { pcm := make([]byte, 480*2*4) // 480 frames, 2 ch, 4 bytes float h := Header{Type: AudioType, Timestamp: 42, Size: int32(len(pcm))} w := WaveHeader{Format: AudioFormatF32, SampleRate: 48000, Speakers: 2, Frames: 480} wire, err := WritePacket(h, nil, &w, pcm) if err != nil { t.Fatalf("WritePacket: %v", err) } if len(wire) != headerSize+waveHeaderSize+len(pcm) { t.Errorf("wire size = %d, want %d", len(wire), headerSize+waveHeaderSize+len(pcm)) } _, gotImg, gotWave, payload, err := ReadPacket(bytes.NewReader(wire)) if err != nil { t.Fatalf("ReadPacket: %v", err) } if gotWave == nil || gotImg != nil { t.Fatalf("expected wave header and no image header") } if *gotWave != w { t.Errorf("wave header mismatch: got %+v want %+v", *gotWave, w) } if !bytes.Equal(payload, pcm) { t.Errorf("pcm payload mismatch") } } // TestBuildWavePacket checks the convenience builder enforces PCM length // vs. the declared format/speakers/frames. func TestBuildWavePacket(t *testing.T) { good := make([]byte, 480*2*4) if _, err := BuildWavePacket(1, AudioFormatF32, 48000, 2, 480, good); err != nil { t.Errorf("valid packet rejected: %v", err) } if _, err := BuildWavePacket(1, AudioFormatF32, 48000, 2, 480, good[:len(good)-1]); err == nil { t.Error("truncated pcm accepted") } u8 := make([]byte, 480) // 1 ch, 480 frames, 1 byte if _, err := BuildWavePacket(1, AudioFormatU8, 48000, 1, 480, u8); err != nil { t.Errorf("u8 packet rejected: %v", err) } } // TestUnsupportedPacketType ensures ReadPacket rejects unknown markers by // feeding it a raw 16-byte header with a non-"JPEG"/"WAVE" type. func TestUnsupportedPacketType(t *testing.T) { var wire [headerSize]byte wire[0] = 'Z' wire[1] = 'Z' wire[2] = 'Z' wire[3] = 'Z' if _, _, _, _, err := ReadPacket(bytes.NewReader(wire[:])); err == nil { t.Error("unknown packet type accepted") } }