Yuv420p to Rgb Conversion with SKSL

47 views
Skip to first unread message

Can Günaydın

unread,
Jan 29, 2024, 8:38:32 AM1/29/24
to skia-discuss
Hello,
I am quite new to Skia, 
I have yuv image 3 byte arrays. I want to delegate the conversion( to rgb) of the image to gpu if it is possible. I have tried this shader code.

 var src = @"
uniform shader yImage;
uniform shader uImage;
uniform shader vImage;
uniform float3 canvasResolution;
uniform float3 frameResolution;
half4 main(float2 coord) {
float2 scale = frameResolution.xy / canvasResolution.xy;
half y = sample(yImage,coord * scale).r - 0.0625;
half u = sample(uImage,coord * scale).r - 0.5;
half v = sample(vImage,coord * scale).r - 0.5;

half r = y + 1.596 * v;
half g = y - 0.813 * v - 0.391 * u;
half b = y + 2.018 * u;
return half4(r,g,b,1.0);
}";


this is giving an output as you see below.
Screenshot 2024-01-28 at 14.13.38.png

Screenshot 2024-01-28 at 14.13.48.png

I use single channel. I have tried Alpha8 and GrayScale, but same result. what can be wrong any idea about it? Cause same math formula works when i try it on opengl. 

Brian Salomon

unread,
Jan 29, 2024, 9:33:21 AM1/29/24
to skia-d...@googlegroups.com
Skia's image shaders generally take the sample position in pixel units. It looks like you need to scale up the U/V plane sampling by a factor of 2 to account for the subsampling.

Not that Skia has APIs that can ingest YUV planes and make a single SkImage from them that is converted to RGB on each draw (SkImages::TextureFromYUVAPixmaps and SkImages::TextureFromYUVATextures).

--
You received this message because you are subscribed to the Google Groups "skia-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/skia-discuss/fad9e2d1-5bae-489c-b8d0-12ce186d96a3n%40googlegroups.com.

Brian Salomon

unread,
Jan 29, 2024, 9:36:19 AM1/29/24
to skia-d...@googlegroups.com
Sorry, scale the UV coords by 1/2.

Can Günaydın

unread,
Jan 29, 2024, 10:10:08 AM1/29/24
to skia-discuss
You make my day, I was struggling with this for 2 days. thank you super much.  code below makes it work.

half y = sample(yImage,coord * scale).r - 0.0625;
half u = sample(uImage,(coord / 2) * scale).r - 0.5;
half v = sample(vImage,(coord / 2) * scale).r - 0.5;

Jim Van Verth

unread,
Jan 29, 2024, 10:13:34 AM1/29/24
to skia-d...@googlegroups.com
I'll reiterate what Brian said, that SkImages::TextureFromYUVAPixmaps and SkImages::TextureFromYUVATextures can take care of this for you. The Ganesh GPU backend also handles odd sizes and any adjustment of sampling to handle siting (Graphite fixes are coming soon).



--

Jim Van Verth |
 Software Engineer | Google.com

Can Günaydın

unread,
Jan 29, 2024, 12:04:16 PM1/29/24
to skia-d...@googlegroups.com
Thank you for the information. For the project that i am working on, i was using skiasharp, but as i understand SkImages::TextureFromYUVAPixmaps and SkImages::TextureFromYUVATextures is not adopted by SkiaSharp. (or maybe it is but i couldn't find it)
Now to check what can i do more with skia, i have built it and i am doing some experiments on it. I will definitely try with SkImages::TextureFromYUVAPixmaps and SkImages::TextureFromYUVATextures. If i can manage to work, my plan is to adopt it with a custom build. Thanks again for all your help.

Reply all
Reply to author
Forward
0 new messages