package generator import ( "encoding/binary" "fmt" "testing" ) func TestV210Sizes(t *testing.T) { tests := []struct { width int activeLine int line int }{ {width: 1920, activeLine: 5120, line: 5120}, {width: 1280, activeLine: 3424, line: 3456}, {width: 100, activeLine: 272, line: 384}, {width: 54, activeLine: 144, line: 256}, {width: 48, activeLine: 128, line: 128}, } for _, tc := range tests { if got := V210ActiveLineSize(tc.width); got != tc.activeLine { t.Errorf("V210ActiveLineSize(%d) = %d, want %d", tc.width, got, tc.activeLine) } if got := V210LineSize(tc.width); got != tc.line { t.Errorf("V210LineSize(%d) = %d, want %d", tc.width, got, tc.line) } if got := V210FrameSize(tc.width, 2); got != tc.line*2 { t.Errorf("V210FrameSize(%d, 2) = %d, want %d", tc.width, got, tc.line*2) } } } func TestAlphaSizes(t *testing.T) { tests := []struct { width int height int lineSize int frameSize int v210aSize int }{ { width: 1920, height: 1080, lineSize: 2560, frameSize: 2_764_800, v210aSize: 8_294_400, }, { width: 1280, height: 720, lineSize: 1708, frameSize: 1_229_760, v210aSize: 3_718_080, }, { width: 100, height: 2, lineSize: 136, frameSize: 272, v210aSize: 1040, }, } for _, tc := range tests { t.Run(fmt.Sprintf("%dx%d", tc.width, tc.height), func(t *testing.T) { if got := AlphaLineSize(tc.width); got != tc.lineSize { t.Errorf("AlphaLineSize(%d) = %d, want %d", tc.width, got, tc.lineSize) } if got := AlphaFrameSize(tc.width, tc.height); got != tc.frameSize { t.Errorf("AlphaFrameSize(%d, %d) = %d, want %d", tc.width, tc.height, got, tc.frameSize) } if got := V210AFrameSize(tc.width, tc.height); got != tc.v210aSize { t.Errorf("V210AFrameSize(%d, %d) = %d, want %d", tc.width, tc.height, got, tc.v210aSize) } if got := V210AFrameSize(tc.width, tc.height) - AlphaFrameSize(tc.width, tc.height); got != V210FrameSize(tc.width, tc.height) { t.Errorf("alpha plane starts at byte %d, want %d", got, V210FrameSize(tc.width, tc.height)) } }) } } func sampleV210(buf []byte, width, x, y int) (yc, cb, cr uint32) { offset := y*V210LineSize(width) + x/6*16 w0 := binary.LittleEndian.Uint32(buf[offset:]) w1 := binary.LittleEndian.Uint32(buf[offset+4:]) w2 := binary.LittleEndian.Uint32(buf[offset+8:]) w3 := binary.LittleEndian.Uint32(buf[offset+12:]) switch x % 6 { case 0: return (w0 >> 10) & 0x3FF, w0 & 0x3FF, (w0 >> 20) & 0x3FF case 1: return w1 & 0x3FF, w0 & 0x3FF, (w0 >> 20) & 0x3FF case 2: return (w1 >> 20) & 0x3FF, (w1 >> 10) & 0x3FF, w2 & 0x3FF case 3: return (w2 >> 10) & 0x3FF, (w1 >> 10) & 0x3FF, w2 & 0x3FF case 4: return w3 & 0x3FF, (w2 >> 20) & 0x3FF, (w3 >> 10) & 0x3FF default: return (w3 >> 20) & 0x3FF, (w2 >> 20) & 0x3FF, (w3 >> 10) & 0x3FF } }