mirror of
https://github.com/pion/mediadevices.git
synced 2025-09-27 04:46:10 +08:00
Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
548cdac668 | ||
![]() |
79f9fc31f6 | ||
![]() |
1f92ea40da | ||
![]() |
4beb7e5a23 | ||
![]() |
9bb5755cd2 |
12
.github/workflows/ci.yaml
vendored
12
.github/workflows/ci.yaml
vendored
@@ -17,9 +17,9 @@ jobs:
|
||||
name: Linux Go ${{ matrix.go }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v2
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: ${{ matrix.go }}
|
||||
- name: Install dependencies
|
||||
@@ -43,9 +43,9 @@ jobs:
|
||||
name: Darwin Go ${{ matrix.go }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v2
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: ${{ matrix.go }}
|
||||
- name: Install dependencies
|
||||
@@ -62,9 +62,9 @@ jobs:
|
||||
name: Check Licenses
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v2
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '1.16'
|
||||
- name: Installing go-licenses
|
||||
|
2
.github/workflows/renovate-go-mod-fix.yaml
vendored
2
.github/workflows/renovate-go-mod-fix.yaml
vendored
@@ -9,7 +9,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 2
|
||||
- name: fix
|
||||
|
2
go.mod
2
go.mod
@@ -10,6 +10,6 @@ require (
|
||||
github.com/pion/logging v0.2.2
|
||||
github.com/pion/rtp v1.7.4
|
||||
github.com/pion/webrtc/v3 v3.1.10
|
||||
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d
|
||||
golang.org/x/image v0.0.0-20220302094943-723b81ca9867
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
)
|
||||
|
4
go.sum
4
go.sum
@@ -100,8 +100,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs=
|
||||
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
|
||||
golang.org/x/image v0.0.0-20220302094943-723b81ca9867 h1:TcHcE0vrmgzNH1v3ppjcMGbhG5+9fMuvOmUYwNEF4q4=
|
||||
golang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
|
@@ -88,9 +88,8 @@ Slice enc_encode(Encoder *e, Frame f, int *eresult) {
|
||||
pic.iPicWidth = f.width;
|
||||
pic.iPicHeight = f.height;
|
||||
pic.iColorFormat = videoFormatI420;
|
||||
// We always received I420 format
|
||||
pic.iStride[0] = pic.iPicWidth;
|
||||
pic.iStride[1] = pic.iStride[2] = pic.iPicWidth / 2;
|
||||
pic.iStride[0] = f.ystride;
|
||||
pic.iStride[1] = pic.iStride[2] = f.cstride;
|
||||
pic.pData[0] = (unsigned char *)f.y;
|
||||
pic.pData[1] = (unsigned char *)f.u;
|
||||
pic.pData[2] = (unsigned char *)f.v;
|
||||
|
@@ -12,6 +12,8 @@ typedef struct Slice {
|
||||
|
||||
typedef struct Frame {
|
||||
void *y, *u, *v;
|
||||
int ystride;
|
||||
int cstride;
|
||||
int height;
|
||||
int width;
|
||||
} Frame;
|
||||
|
@@ -65,11 +65,13 @@ func (e *encoder) Read() ([]byte, func(), error) {
|
||||
bounds := yuvImg.Bounds()
|
||||
var rv C.int
|
||||
s := C.enc_encode(e.engine, C.Frame{
|
||||
y: unsafe.Pointer(&yuvImg.Y[0]),
|
||||
u: unsafe.Pointer(&yuvImg.Cb[0]),
|
||||
v: unsafe.Pointer(&yuvImg.Cr[0]),
|
||||
height: C.int(bounds.Max.Y - bounds.Min.Y),
|
||||
width: C.int(bounds.Max.X - bounds.Min.X),
|
||||
y: unsafe.Pointer(&yuvImg.Y[0]),
|
||||
u: unsafe.Pointer(&yuvImg.Cb[0]),
|
||||
v: unsafe.Pointer(&yuvImg.Cr[0]),
|
||||
ystride: C.int(yuvImg.YStride),
|
||||
cstride: C.int(yuvImg.CStride),
|
||||
height: C.int(bounds.Max.Y - bounds.Min.Y),
|
||||
width: C.int(bounds.Max.X - bounds.Min.X),
|
||||
}, &rv)
|
||||
if err := errResult(rv); err != nil {
|
||||
return nil, func() {}, fmt.Errorf("failed in encoding: %v", err)
|
||||
|
@@ -109,7 +109,7 @@ func Scale(width, height int, scaler Scaler) TransformFunc {
|
||||
yDy := rect.Dy()
|
||||
cRect := fixedRect(rect, i1.SubsampleRatio)
|
||||
cDx := cRect.Dx()
|
||||
cDy := cRect.Dx()
|
||||
cDy := cRect.Dy()
|
||||
yLen := yDx * yDy
|
||||
cLen := cDx * cDy
|
||||
if len(imgDst.Y) < yLen {
|
||||
|
@@ -36,6 +36,32 @@ func TestScale(t *testing.T) {
|
||||
Rect: image.Rect(0, 0, 2, 2),
|
||||
},
|
||||
},
|
||||
"RGBASameSize": {
|
||||
src: &image.RGBA{
|
||||
Pix: []uint8{
|
||||
// R G B A | R G B A | R G B A | R G B A
|
||||
0x80, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF,
|
||||
0x80, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF,
|
||||
0x00, 0x40, 0x00, 0xFF, 0x00, 0x40, 0x00, 0xFF, 0x00, 0x00, 0x60, 0xFF, 0x00, 0x00, 0x60, 0xFF,
|
||||
0x00, 0x40, 0x00, 0xFF, 0x00, 0x40, 0x00, 0xFF, 0x00, 0x00, 0x60, 0xFF, 0x00, 0x00, 0x60, 0xFF,
|
||||
},
|
||||
Stride: 16,
|
||||
Rect: image.Rect(0, 0, 4, 4),
|
||||
},
|
||||
width: 4,
|
||||
height: 4,
|
||||
expected: &image.RGBA{
|
||||
Pix: []uint8{
|
||||
// R G B A | R G B A | R G B A | R G B A
|
||||
0x80, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF,
|
||||
0x80, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF,
|
||||
0x00, 0x40, 0x00, 0xFF, 0x00, 0x40, 0x00, 0xFF, 0x00, 0x00, 0x60, 0xFF, 0x00, 0x00, 0x60, 0xFF,
|
||||
0x00, 0x40, 0x00, 0xFF, 0x00, 0x40, 0x00, 0xFF, 0x00, 0x00, 0x60, 0xFF, 0x00, 0x00, 0x60, 0xFF,
|
||||
},
|
||||
Stride: 16,
|
||||
Rect: image.Rect(0, 0, 4, 4),
|
||||
},
|
||||
},
|
||||
"I444": {
|
||||
src: &image.YCbCr{
|
||||
SubsampleRatio: image.YCbCrSubsampleRatio444,
|
||||
@@ -91,6 +117,70 @@ func TestScale(t *testing.T) {
|
||||
Rect: image.Rect(0, 0, 3, 3),
|
||||
},
|
||||
},
|
||||
"I444SameSize": {
|
||||
src: &image.YCbCr{
|
||||
SubsampleRatio: image.YCbCrSubsampleRatio444,
|
||||
Y: []uint8{
|
||||
0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00,
|
||||
0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x40,
|
||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x40,
|
||||
0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
|
||||
},
|
||||
Cb: []uint8{
|
||||
0x20, 0x20, 0x80, 0x80, 0x80, 0x80,
|
||||
0x20, 0x20, 0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80, 0xC0, 0xC0,
|
||||
0x80, 0x80, 0x80, 0x80, 0xC0, 0xC0,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
},
|
||||
Cr: []uint8{
|
||||
0xE0, 0xE0, 0x80, 0x80, 0x80, 0x80,
|
||||
0xE0, 0xE0, 0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x40, 0x40, 0x80, 0x80,
|
||||
0x80, 0x80, 0x40, 0x40, 0x80, 0x80,
|
||||
},
|
||||
YStride: 6,
|
||||
CStride: 6,
|
||||
Rect: image.Rect(0, 0, 6, 6),
|
||||
},
|
||||
width: 6,
|
||||
height: 6,
|
||||
expected: &image.YCbCr{
|
||||
SubsampleRatio: image.YCbCrSubsampleRatio444,
|
||||
Y: []uint8{
|
||||
0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00,
|
||||
0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x40,
|
||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x40,
|
||||
0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
|
||||
},
|
||||
Cb: []uint8{
|
||||
0x20, 0x20, 0x80, 0x80, 0x80, 0x80,
|
||||
0x20, 0x20, 0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80, 0xC0, 0xC0,
|
||||
0x80, 0x80, 0x80, 0x80, 0xC0, 0xC0,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
},
|
||||
Cr: []uint8{
|
||||
0xE0, 0xE0, 0x80, 0x80, 0x80, 0x80,
|
||||
0xE0, 0xE0, 0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x40, 0x40, 0x80, 0x80,
|
||||
0x80, 0x80, 0x40, 0x40, 0x80, 0x80,
|
||||
},
|
||||
YStride: 6,
|
||||
CStride: 6,
|
||||
Rect: image.Rect(0, 0, 6, 6),
|
||||
},
|
||||
},
|
||||
"I422": {
|
||||
src: &image.YCbCr{
|
||||
SubsampleRatio: image.YCbCrSubsampleRatio422,
|
||||
@@ -155,6 +245,82 @@ func TestScale(t *testing.T) {
|
||||
Rect: image.Rect(0, 0, 4, 4),
|
||||
},
|
||||
},
|
||||
"I422SameSize": {
|
||||
src: &image.YCbCr{
|
||||
SubsampleRatio: image.YCbCrSubsampleRatio422,
|
||||
Y: []uint8{
|
||||
0xF0, 0xF0, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||
0xF0, 0xF0, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0x80, 0x30, 0x30, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0x80, 0x30, 0x30, 0x00, 0x00,
|
||||
},
|
||||
Cb: []uint8{
|
||||
0x20, 0x20, 0x80, 0x80,
|
||||
0x20, 0x20, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0xE0, 0xE0,
|
||||
0x80, 0x80, 0xE0, 0xE0,
|
||||
},
|
||||
Cr: []uint8{
|
||||
0xE0, 0xE0, 0x80, 0x80,
|
||||
0xE0, 0xE0, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80,
|
||||
0xF0, 0xF0, 0x40, 0x40,
|
||||
0xF0, 0xF0, 0x40, 0x40,
|
||||
},
|
||||
YStride: 8,
|
||||
CStride: 4,
|
||||
Rect: image.Rect(0, 0, 8, 8),
|
||||
},
|
||||
width: 8,
|
||||
height: 8,
|
||||
expected: &image.YCbCr{
|
||||
SubsampleRatio: image.YCbCrSubsampleRatio422,
|
||||
Y: []uint8{
|
||||
0xF0, 0xF0, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||
0xF0, 0xF0, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0x80, 0x30, 0x30, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0x80, 0x30, 0x30, 0x00, 0x00,
|
||||
},
|
||||
Cb: []uint8{
|
||||
0x20, 0x20, 0x80, 0x80,
|
||||
0x20, 0x20, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0xE0, 0xE0,
|
||||
0x80, 0x80, 0xE0, 0xE0,
|
||||
},
|
||||
Cr: []uint8{
|
||||
0xE0, 0xE0, 0x80, 0x80,
|
||||
0xE0, 0xE0, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80,
|
||||
0xF0, 0xF0, 0x40, 0x40,
|
||||
0xF0, 0xF0, 0x40, 0x40,
|
||||
},
|
||||
YStride: 8,
|
||||
CStride: 4,
|
||||
Rect: image.Rect(0, 0, 8, 8),
|
||||
},
|
||||
},
|
||||
"I420": {
|
||||
src: &image.YCbCr{
|
||||
SubsampleRatio: image.YCbCrSubsampleRatio420,
|
||||
@@ -207,6 +373,118 @@ func TestScale(t *testing.T) {
|
||||
Rect: image.Rect(0, 0, 4, 4),
|
||||
},
|
||||
},
|
||||
"I420SameSize": {
|
||||
src: &image.YCbCr{
|
||||
SubsampleRatio: image.YCbCrSubsampleRatio420,
|
||||
Y: []uint8{
|
||||
0xF0, 0xF0, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||
0xF0, 0xF0, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0x80, 0x30, 0x30, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0x80, 0x30, 0x30, 0x00, 0x00,
|
||||
},
|
||||
Cb: []uint8{
|
||||
0x20, 0x20, 0x80, 0x80,
|
||||
0x20, 0x20, 0x80, 0x80,
|
||||
0x80, 0x80, 0xE0, 0xE0,
|
||||
0x80, 0x80, 0xE0, 0xE0,
|
||||
},
|
||||
Cr: []uint8{
|
||||
0xE0, 0xE0, 0x80, 0x80,
|
||||
0xE0, 0xE0, 0x80, 0x80,
|
||||
0xF0, 0xF0, 0x40, 0x40,
|
||||
0xF0, 0xF0, 0x40, 0x40,
|
||||
},
|
||||
YStride: 8,
|
||||
CStride: 4,
|
||||
Rect: image.Rect(0, 0, 8, 8),
|
||||
},
|
||||
width: 8,
|
||||
height: 8,
|
||||
expected: &image.YCbCr{
|
||||
SubsampleRatio: image.YCbCrSubsampleRatio420,
|
||||
Y: []uint8{
|
||||
0xF0, 0xF0, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||
0xF0, 0xF0, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0x80, 0x30, 0x30, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0x80, 0x30, 0x30, 0x00, 0x00,
|
||||
},
|
||||
Cb: []uint8{
|
||||
0x20, 0x20, 0x80, 0x80,
|
||||
0x20, 0x20, 0x80, 0x80,
|
||||
0x80, 0x80, 0xE0, 0xE0,
|
||||
0x80, 0x80, 0xE0, 0xE0,
|
||||
},
|
||||
Cr: []uint8{
|
||||
0xE0, 0xE0, 0x80, 0x80,
|
||||
0xE0, 0xE0, 0x80, 0x80,
|
||||
0xF0, 0xF0, 0x40, 0x40,
|
||||
0xF0, 0xF0, 0x40, 0x40,
|
||||
},
|
||||
YStride: 8,
|
||||
CStride: 4,
|
||||
Rect: image.Rect(0, 0, 8, 8),
|
||||
},
|
||||
},
|
||||
"I420NonSquareImage": {
|
||||
src: &image.YCbCr{
|
||||
SubsampleRatio: image.YCbCrSubsampleRatio420,
|
||||
Y: []uint8{
|
||||
0xF0, 0xF0, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x10, 0x10,
|
||||
0xF0, 0xF0, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x10, 0x10,
|
||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0x80, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0x80, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00,
|
||||
},
|
||||
Cb: []uint8{
|
||||
0x20, 0x20, 0x80, 0x80, 0x50, 0x50,
|
||||
0x20, 0x20, 0x80, 0x80, 0x50, 0x50,
|
||||
0x80, 0x80, 0xE0, 0xE0, 0x30, 0x30,
|
||||
0x80, 0x80, 0xE0, 0xE0, 0x30, 0x30,
|
||||
},
|
||||
Cr: []uint8{
|
||||
0xE0, 0xE0, 0x80, 0x80, 0xB0, 0xB0,
|
||||
0xE0, 0xE0, 0x80, 0x80, 0xB0, 0xB0,
|
||||
0xF0, 0xF0, 0x40, 0x40, 0xC0, 0xC0,
|
||||
0xF0, 0xF0, 0x40, 0x40, 0xC0, 0xC0,
|
||||
},
|
||||
YStride: 12,
|
||||
CStride: 6,
|
||||
Rect: image.Rect(0, 0, 12, 8),
|
||||
},
|
||||
width: 6,
|
||||
height: 4,
|
||||
expected: &image.YCbCr{
|
||||
SubsampleRatio: image.YCbCrSubsampleRatio420,
|
||||
Y: []uint8{
|
||||
0xF0, 0x10, 0x00, 0x00, 0xF0, 0x10,
|
||||
0x00, 0x00, 0x40, 0x00, 0x40, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x80, 0x30, 0x00, 0x30, 0x00,
|
||||
},
|
||||
Cb: []uint8{
|
||||
0x20, 0x80, 0x50,
|
||||
0x80, 0xE0, 0x30,
|
||||
},
|
||||
Cr: []uint8{
|
||||
0xE0, 0x80, 0xB0,
|
||||
0xF0, 0x40, 0xC0,
|
||||
},
|
||||
YStride: 6,
|
||||
CStride: 3,
|
||||
Rect: image.Rect(0, 0, 6, 4),
|
||||
},
|
||||
},
|
||||
}
|
||||
for name, algo := range scalerTestAlgos {
|
||||
algo := algo
|
||||
@@ -247,6 +525,100 @@ func TestScale(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestScaleFastBoxSampling(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
src image.Image
|
||||
width, height int
|
||||
expected image.Image
|
||||
}{
|
||||
"I420NonSquareImage": {
|
||||
src: &image.YCbCr{
|
||||
SubsampleRatio: image.YCbCrSubsampleRatio420,
|
||||
Y: []uint8{
|
||||
0xF0, 0xF0, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x10, 0x10,
|
||||
0xF0, 0xF0, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x10, 0x10,
|
||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0x80, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0x80, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00,
|
||||
},
|
||||
Cb: []uint8{
|
||||
0x20, 0x20, 0x80, 0x80, 0x50, 0x50,
|
||||
0x20, 0x20, 0x80, 0x80, 0x50, 0x50,
|
||||
0x80, 0x80, 0xE0, 0xE0, 0x30, 0x30,
|
||||
0x80, 0x80, 0xE0, 0xE0, 0x30, 0x30,
|
||||
},
|
||||
Cr: []uint8{
|
||||
0xE0, 0xE0, 0x80, 0x80, 0xB0, 0xB0,
|
||||
0xE0, 0xE0, 0x80, 0x80, 0xB0, 0xB0,
|
||||
0xF0, 0xF0, 0x40, 0x40, 0xC0, 0xC0,
|
||||
0xF0, 0xF0, 0x40, 0x40, 0xC0, 0xC0,
|
||||
},
|
||||
YStride: 12,
|
||||
CStride: 6,
|
||||
Rect: image.Rect(0, 0, 12, 8),
|
||||
},
|
||||
width: 6,
|
||||
height: 4,
|
||||
expected: &image.YCbCr{
|
||||
SubsampleRatio: image.YCbCrSubsampleRatio420,
|
||||
Y: []uint8{
|
||||
0xF0, 0x80, 0x08, 0x00, 0x78, 0x80,
|
||||
0x08, 0x00, 0x20, 0x20, 0x20, 0x20,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x40, 0x58, 0x18, 0x18, 0x18,
|
||||
},
|
||||
Cb: []uint8{
|
||||
0x20, 0x50, 0x68,
|
||||
0x68, 0xB0, 0x88,
|
||||
},
|
||||
Cr: []uint8{
|
||||
0xE0, 0xB0, 0x98,
|
||||
0xD0, 0x98, 0x80,
|
||||
},
|
||||
YStride: 6,
|
||||
CStride: 3,
|
||||
Rect: image.Rect(0, 0, 6, 4),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for name, c := range cases {
|
||||
c := c
|
||||
t.Run(name, func(t *testing.T) {
|
||||
trans := Scale(c.width, c.height, ScalerFastBoxSampling)
|
||||
r := trans(ReaderFunc(func() (image.Image, func(), error) {
|
||||
return c.src, func() {}, nil
|
||||
}))
|
||||
for i := 0; i < 4; i++ {
|
||||
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\nrepeat: %d", c.expected, out, i)
|
||||
}
|
||||
// Destroy output contents
|
||||
switch v := out.(type) {
|
||||
case *image.RGBA:
|
||||
v.Stride = 10
|
||||
v.Pix = v.Pix[:1]
|
||||
v.Rect.Max.X = 1
|
||||
case *image.YCbCr:
|
||||
v.YStride = 10
|
||||
v.CStride = 100
|
||||
v.Y = v.Y[:1]
|
||||
v.Cb = v.Cb[:2]
|
||||
v.Cr = v.Cr[:1]
|
||||
v.Rect.Max.X = 1
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkScale(b *testing.B) {
|
||||
for name, algo := range scalerBenchAlgos {
|
||||
algo := algo
|
||||
|
@@ -29,7 +29,7 @@ void fastBoxSampling(
|
||||
const int sw, const int sh, const int sstride,
|
||||
uint32_t* tmp)
|
||||
{
|
||||
memset(tmp, 0, dw * dh * ch);
|
||||
memset(tmp, 0, dw * dh * ch * sizeof(tmp[0]));
|
||||
|
||||
for (int sy = 0; sy < sh; sy++)
|
||||
{
|
||||
|
@@ -30,10 +30,18 @@ func (p *rgbLikeYCbCr) At(x, y int) color.Color {
|
||||
}
|
||||
|
||||
func (p *rgbLikeYCbCr) Set(x, y int, c color.Color) {
|
||||
rgb := c.(*color.RGBA64)
|
||||
p.y.SetGray(x, y, color.Gray{uint8(rgb.R / 0x100)})
|
||||
if (image.Point{x, y}.In(p.cb.Rect)) {
|
||||
p.cb.SetGray(x, y, color.Gray{uint8(rgb.G / 0x100)})
|
||||
p.cr.SetGray(x, y, color.Gray{uint8(rgb.B / 0x100)})
|
||||
switch v := c.(type) {
|
||||
case color.RGBA:
|
||||
p.y.SetGray(x, y, color.Gray{v.R})
|
||||
if (image.Point{x, y}.In(p.cb.Rect)) {
|
||||
p.cb.SetGray(x, y, color.Gray{v.G})
|
||||
p.cr.SetGray(x, y, color.Gray{v.B})
|
||||
}
|
||||
case *color.RGBA64:
|
||||
p.y.SetGray(x, y, color.Gray{uint8(v.R / 0x100)})
|
||||
if (image.Point{x, y}.In(p.cb.Rect)) {
|
||||
p.cb.SetGray(x, y, color.Gray{uint8(v.G / 0x100)})
|
||||
p.cr.SetGray(x, y, color.Gray{uint8(v.B / 0x100)})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user