mirror of
https://github.com/pion/mediadevices.git
synced 2025-10-05 00:32:44 +08:00
271 lines
6.4 KiB
Go
271 lines
6.4 KiB
Go
package video
|
|
|
|
import (
|
|
"image"
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
var imageSizes = map[string][2]int{
|
|
"480p": [2]int{720, 480},
|
|
"1080p": [2]int{1920, 1080},
|
|
}
|
|
|
|
func TestToI420(t *testing.T) {
|
|
cases := map[string]struct {
|
|
src image.Image
|
|
expected image.Image
|
|
}{
|
|
"I444": {
|
|
src: &image.YCbCr{
|
|
SubsampleRatio: image.YCbCrSubsampleRatio444,
|
|
Y: []uint8{
|
|
0xF0, 0x10, 0x00, 0x00,
|
|
0x00, 0x00, 0x40, 0x00,
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x80, 0x30, 0x00,
|
|
},
|
|
Cb: []uint8{
|
|
0xF0, 0xF0, 0x80, 0x80,
|
|
0xF0, 0xF0, 0x80, 0x80,
|
|
0x80, 0x80, 0x30, 0x30,
|
|
0x80, 0x80, 0x30, 0x30,
|
|
},
|
|
Cr: []uint8{
|
|
0x10, 0x10, 0x40, 0x40,
|
|
0x10, 0x10, 0x40, 0x40,
|
|
0x80, 0x80, 0x80, 0x80,
|
|
0x80, 0x80, 0x80, 0x80,
|
|
},
|
|
YStride: 4,
|
|
CStride: 4,
|
|
Rect: image.Rect(0, 0, 4, 4),
|
|
},
|
|
expected: &image.YCbCr{
|
|
SubsampleRatio: image.YCbCrSubsampleRatio420,
|
|
Y: []uint8{
|
|
0xF0, 0x10, 0x00, 0x00,
|
|
0x00, 0x00, 0x40, 0x00,
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x80, 0x30, 0x00,
|
|
},
|
|
Cb: []uint8{
|
|
0xF0, 0x80,
|
|
0x80, 0x30,
|
|
},
|
|
Cr: []uint8{
|
|
0x10, 0x40,
|
|
0x80, 0x80,
|
|
},
|
|
YStride: 4,
|
|
CStride: 2,
|
|
Rect: image.Rect(0, 0, 4, 4),
|
|
},
|
|
},
|
|
"I422": {
|
|
src: &image.YCbCr{
|
|
SubsampleRatio: image.YCbCrSubsampleRatio422,
|
|
Y: []uint8{
|
|
0xF0, 0x10, 0x00, 0x00,
|
|
0x00, 0x00, 0x40, 0x00,
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x80, 0x30, 0x00,
|
|
},
|
|
Cb: []uint8{
|
|
0xF0, 0x80,
|
|
0xF0, 0x80,
|
|
0x80, 0x30,
|
|
0x80, 0x30,
|
|
},
|
|
Cr: []uint8{
|
|
0x10, 0x40,
|
|
0x10, 0x40,
|
|
0x80, 0x80,
|
|
0x80, 0x80,
|
|
},
|
|
YStride: 4,
|
|
CStride: 2,
|
|
Rect: image.Rect(0, 0, 4, 4),
|
|
},
|
|
expected: &image.YCbCr{
|
|
SubsampleRatio: image.YCbCrSubsampleRatio420,
|
|
Y: []uint8{
|
|
0xF0, 0x10, 0x00, 0x00,
|
|
0x00, 0x00, 0x40, 0x00,
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x80, 0x30, 0x00,
|
|
},
|
|
Cb: []uint8{
|
|
0xF0, 0x80,
|
|
0x80, 0x30,
|
|
},
|
|
Cr: []uint8{
|
|
0x10, 0x40,
|
|
0x80, 0x80,
|
|
},
|
|
YStride: 4,
|
|
CStride: 2,
|
|
Rect: image.Rect(0, 0, 4, 4),
|
|
},
|
|
},
|
|
"RGBA": {
|
|
src: &image.RGBA{
|
|
Pix: []uint8{
|
|
0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF,
|
|
0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF,
|
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF,
|
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF,
|
|
},
|
|
Stride: 16,
|
|
Rect: image.Rect(0, 0, 4, 4),
|
|
},
|
|
expected: &image.YCbCr{
|
|
SubsampleRatio: image.YCbCrSubsampleRatio420,
|
|
Y: []uint8{
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0xFF, 0xFF, 0x00, 0x00,
|
|
0xFF, 0xFF, 0x00, 0x00,
|
|
},
|
|
Cb: []uint8{
|
|
0x80, 0x80,
|
|
0x80, 0x80,
|
|
},
|
|
Cr: []uint8{
|
|
0x80, 0x80,
|
|
0x80, 0x80,
|
|
},
|
|
YStride: 4,
|
|
CStride: 2,
|
|
Rect: image.Rect(0, 0, 4, 4),
|
|
},
|
|
},
|
|
}
|
|
for name, c := range cases {
|
|
c := c
|
|
t.Run(name, func(t *testing.T) {
|
|
r := ToI420(ReaderFunc(func() (image.Image, func(), error) {
|
|
return c.src, func() {}, nil
|
|
}))
|
|
out, _, err := r.Read()
|
|
if err != nil {
|
|
t.Fatalf("Unexpected error: %v", err)
|
|
}
|
|
if !reflect.DeepEqual(c.expected, out) {
|
|
t.Errorf("Expected output image:\n%v\ngot:\n%v", c.expected, out)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestToRGBA(t *testing.T) {
|
|
cases := map[string]struct {
|
|
src image.Image
|
|
expected image.Image
|
|
}{
|
|
"I444": {
|
|
src: &image.YCbCr{
|
|
SubsampleRatio: image.YCbCrSubsampleRatio420,
|
|
Y: []uint8{
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0xFF, 0xFF, 0x00, 0x00,
|
|
0xFF, 0xFF, 0x00, 0x00,
|
|
},
|
|
Cb: []uint8{
|
|
0x80, 0x80,
|
|
0x80, 0x80,
|
|
},
|
|
Cr: []uint8{
|
|
0x80, 0x80,
|
|
0x80, 0x80,
|
|
},
|
|
YStride: 4,
|
|
CStride: 2,
|
|
Rect: image.Rect(0, 0, 4, 4),
|
|
},
|
|
expected: &image.RGBA{
|
|
Pix: []uint8{
|
|
0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF,
|
|
0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF,
|
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF,
|
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF,
|
|
},
|
|
Stride: 16,
|
|
Rect: image.Rect(0, 0, 4, 4),
|
|
},
|
|
},
|
|
}
|
|
for name, c := range cases {
|
|
c := c
|
|
t.Run(name, func(t *testing.T) {
|
|
r := ToRGBA(ReaderFunc(func() (image.Image, func(), error) {
|
|
return c.src, func() {}, nil
|
|
}))
|
|
out, _, err := r.Read()
|
|
if err != nil {
|
|
t.Fatalf("Unexpected error: %v", err)
|
|
}
|
|
if !reflect.DeepEqual(c.expected, out) {
|
|
t.Errorf("Expected output image:\n%v\ngot:\n%v", c.expected, out)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func BenchmarkToI420(b *testing.B) {
|
|
for name, sz := range imageSizes {
|
|
cases := map[string]image.Image{
|
|
"I444": image.NewYCbCr(image.Rect(0, 0, sz[0], sz[1]), image.YCbCrSubsampleRatio444),
|
|
"I422": image.NewYCbCr(image.Rect(0, 0, sz[0], sz[1]), image.YCbCrSubsampleRatio422),
|
|
"I420": image.NewYCbCr(image.Rect(0, 0, sz[0], sz[1]), image.YCbCrSubsampleRatio420),
|
|
"RGBA": image.NewRGBA(image.Rect(0, 0, sz[0], sz[1])),
|
|
}
|
|
b.Run(name, func(b *testing.B) {
|
|
for name, img := range cases {
|
|
img := img
|
|
b.Run(name, func(b *testing.B) {
|
|
r := ToI420(ReaderFunc(func() (image.Image, func(), error) {
|
|
return img, func() {}, nil
|
|
}))
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
_, _, err := r.Read()
|
|
if err != nil {
|
|
b.Fatalf("Unexpected error: %v", err)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func BenchmarkToRGBA(b *testing.B) {
|
|
for name, sz := range imageSizes {
|
|
cases := map[string]image.Image{
|
|
"I444": image.NewYCbCr(image.Rect(0, 0, sz[0], sz[1]), image.YCbCrSubsampleRatio444),
|
|
"I422": image.NewYCbCr(image.Rect(0, 0, sz[0], sz[1]), image.YCbCrSubsampleRatio422),
|
|
"I420": image.NewYCbCr(image.Rect(0, 0, sz[0], sz[1]), image.YCbCrSubsampleRatio420),
|
|
"RGBA": image.NewRGBA(image.Rect(0, 0, sz[0], sz[1])),
|
|
}
|
|
b.Run(name, func(b *testing.B) {
|
|
for name, img := range cases {
|
|
img := img
|
|
b.Run(name, func(b *testing.B) {
|
|
r := ToRGBA(ReaderFunc(func() (image.Image, func(), error) {
|
|
return img, func() {}, nil
|
|
}))
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
_, _, err := r.Read()
|
|
if err != nil {
|
|
b.Fatalf("Unexpected error: %v", err)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
})
|
|
}
|
|
}
|