-
Notifications
You must be signed in to change notification settings - Fork 125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add decoder support for pixel format BGRA & ARGB #315
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package frame | ||
|
||
import ( | ||
"fmt" | ||
"image" | ||
"math/bits" | ||
"unsafe" | ||
) | ||
|
||
func decodeARGB(frame []byte, width, height int) (image.Image, func(), error) { | ||
size := 4 * width * height | ||
if size > len(frame) { | ||
return nil, func() {}, fmt.Errorf("frame length (%d) less than expected (%d)", len(frame), size) | ||
} | ||
r := image.Rect(0, 0, width, height) | ||
for i := 0; i < size; i += 4 { | ||
*(*uint32)(unsafe.Pointer(&frame[i])) = func(v uint32) uint32 { | ||
return (v & 0xFF00FF00) | (v&0xFF)<<16 | (v&0xFF0000)>>16 | ||
}(*(*uint32)(unsafe.Pointer(&frame[i]))) | ||
//frame[i], frame[i+2] = frame[i+2], frame[i] | ||
} | ||
return &image.RGBA{ | ||
Pix: frame[:size:size], | ||
Stride: 4 * r.Dx(), | ||
Rect: r, | ||
}, func() {}, nil | ||
} | ||
|
||
func decodeBGRA(frame []byte, width, height int) (image.Image, func(), error) { | ||
size := 4 * width * height | ||
if size > len(frame) { | ||
return nil, func() {}, fmt.Errorf("frame length (%d) less than expected (%d)", len(frame), size) | ||
} | ||
r := image.Rect(0, 0, width, height) | ||
for i := 0; i < size; i += 4 { | ||
*(*uint32)(unsafe.Pointer(&frame[i])) = bits.RotateLeft32(*(*uint32)(unsafe.Pointer(&frame[i])), -8) | ||
//frame[i], frame[i+1], frame[i+2], frame[i+3] = frame[i+1], frame[i+2], frame[i+3], frame[i] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
} | ||
return &image.RGBA{ | ||
Pix: frame[:size:size], | ||
Stride: 4 * r.Dx(), | ||
Rect: r, | ||
}, func() {}, nil | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,48 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
package frame | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"fmt" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"testing" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be nice to have a simple test like: mediadevices/pkg/frame/yuv_test.go Lines 10 to 41 in dafd208
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
func BenchmarkDecodeBGRA(b *testing.B) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
sizes := []struct { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
width, height int | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{640, 480}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{1920, 1080}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for _, sz := range sizes { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
sz := sz | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
b.Run(fmt.Sprintf("%dx%d", sz.width, sz.height), func(b *testing.B) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
input := make([]byte, sz.width*sz.height*4) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for i := 0; i < b.N; i++ { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
_, _, err := decodeBGRA(input, sz.width, sz.height) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
b.Fatal(err) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
func BenchmarkDecodeARGB(b *testing.B) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
sizes := []struct { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
width, height int | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{640, 480}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{1920, 1080}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for _, sz := range sizes { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
sz := sz | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
b.Run(fmt.Sprintf("%dx%d", sz.width, sz.height), func(b *testing.B) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
input := make([]byte, sz.width*sz.height*4) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for i := 0; i < b.N; i++ { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
_, _, err := decodeARGB(input, sz.width, sz.height) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
b.Fatal(err) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like a conversion from
ARGB
toGRAB
. (frame[i]
isA
andframe[i+2]
isG
in the original ARGB data)Maybe the implementations of
decodeARGB
anddecodeBGRA
are swapped?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it only matters to the name of the pixel format.
according to libyuv formats:
and I use the FOURCC_* naming to to name
frame.FormatBGRA
andframe.FormatARGB
which results a similar mapping inavfoundation
pkg.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I misread endian. (It should be little endian on x86 and ARM)
This func seems converting 0xXXYYZZWW (input) to 0xXXWWZZYY (output).
As the output byte order for
image.RGBA
is RGBA order (XX=A, WW=B, ZZ=G, YY=R on little endian uint32), input byte order shoud be BGRA.I guess
https://github.com/pion/mediadevices/pull/315/files#diff-99707109ce57457c8ab1161707d059373858d14ae66e06aed05c50501e29eaa6R148-R153
https://github.com/pion/mediadevices/pull/315/files#diff-99707109ce57457c8ab1161707d059373858d14ae66e06aed05c50501e29eaa6R179-R184
are reversed and name of
decodeARGB
anddecodeBGRA
should be swapped?(I don't have any Macintosh computers, so I couldn't test it on the real environment.)