-
Notifications
You must be signed in to change notification settings - Fork 138
Add decoder support for pixel format BGRA & ARGB #315
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
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] | ||
|
Member
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" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Member
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
ARGBtoGRAB. (frame[i]isAandframe[i+2]isGin the original ARGB data)Maybe the implementations of
decodeARGBanddecodeBGRAare 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.FormatBGRAandframe.FormatARGBwhich results a similar mapping inavfoundationpkg.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.RGBAis 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
decodeARGBanddecodeBGRAshould be swapped?(I don't have any Macintosh computers, so I couldn't test it on the real environment.)