Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion. Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules. |
6th July 2015, 21:24 | #1 | Link |
Soul Architect
Join Date: Apr 2014
Posts: 2,559
|
Convert from YV12 to Lab
In an attempt to translate SuperRes shader to AviSynth, it deals with the Lab color space. That's not supported in AviSynth and I'm not finding anything that converts the color space to Lab.
Can AviSynth support Lab? Has anything been written to convert from YV12 to Lab and from Lab to RGB32? Where can I find the source code of ConvertToRGB32? Anything else I should know about this? |
7th July 2015, 03:53 | #4 | Link | |
Soul Architect
Join Date: Apr 2014
Posts: 2,559
|
Could you expand on this?
Quote:
Parsing the data back and forth to float in c++ can be done. The question is, can AviSynth store all that data in its Clip objects? If not, then another option would be to code the whole thing within C++ and use internal buffers without passing Lab frame data back.
__________________
FrameRateConverter | AvisynthShader | AvsFilterNet | Natural Grounding Player with Yin Media Encoder, 432hz Player, Powerliminals Player and Audio Video Muxer Last edited by MysteryX; 7th July 2015 at 04:13. |
|
7th July 2015, 08:42 | #5 | Link |
Soul Architect
Join Date: Apr 2014
Posts: 2,559
|
I need to have float4 for each pixel in Lab. I found this in AviSynth's source code to convert YUV data into into RGB. Then I can use some other code to convert from RGB to Lab. But... what is this doing? YUV stores the data of 2 pixels at once, so ideally I would return float4x2 as RGB and then convert those two pixels to Lab. The last float will contain some other data.
This code doesn't seem to be doing exactly that... and then what about color matrix? inline void YUV2RGB2(int y, int u0, int u1, int v0, int v1, BYTE* out) { const int crv = int(1.596*32768+0.5); const int cgv = int(0.813*32768+0.5); const int cgu = int(0.391*32768+0.5); const int cbu = int(2.018*32768+0.5); const int scaled_y = (y - 16) * int((255.0/219.0)*65536+0.5); out[0] = ScaledPixelClip(scaled_y + (u0+u1-256) * cbu); // blue out[1] = ScaledPixelClip(scaled_y - (u0+u1-256) * cgu - (v0+v1-256) * cgv); // green out[2] = ScaledPixelClip(scaled_y + (v0+v1-256) * crv); // red } How can I loop through the YV12 source frame data, extract each pairs of pixels, and convert them into RGB? Or can I simply call ConvertToRGB function within my code? It expect a clip but what I have is a frame, so how can I call it?
__________________
FrameRateConverter | AvisynthShader | AvsFilterNet | Natural Grounding Player with Yin Media Encoder, 432hz Player, Powerliminals Player and Audio Video Muxer Last edited by MysteryX; 7th July 2015 at 08:45. |
7th July 2015, 09:21 | #6 | Link |
Angel of Night
Join Date: Nov 2004
Location: Tangled in the silks
Posts: 9,559
|
Use 3 RGBA clips -- where each of RGBA is actually a 32-bit float, doubly handy since the interleaved nature means fast, easy memory access. The three clips should probably be stacked into one for convenience. Tada, new colorspace, just like 16-bit stacked. Fizick did this with MVTools, the output of MSuper is a clip that is really just a bunch of floating-point values.
To read and write, you should be able to cast GetWritePtr to float and work with it fairly easily. Just create convenience functions to separate the stack into each channel. Don't use ConvertToRGB, you lose precision with each conversion. Use DitherTools to work in 16-bit or just convert directly from YUV to float RGB to float LAB. |
7th July 2015, 23:40 | #9 | Link |
Soul Architect
Join Date: Apr 2014
Posts: 2,559
|
Hah. Everybody has a different idea about a detail like this.
I think Shader support should be part of AviSynth's core, and would allow for GPU-support. And this should be done "right" by a master AviSynth developer. It shouldn't be difficult, but if it is to be done, and if it is to become a core component, it should be done right. |
8th July 2015, 01:25 | #10 | Link |
Soul Architect
Join Date: Apr 2014
Posts: 2,559
|
In EEDI3's code (the only one that compiled out-of-the-box for me), it has planar functions like convYUY2to422 and conv444toRGB24 that are highly optimized.
What would be needed is a similar function but that converts from YUY2 to 444 as float instead of int. Then it would be easy to loop through the pixels and convert the float values from RGB to Lab one by one. Float data may be necessary for doing any kind of work with shaders. |
8th July 2015, 02:35 | #11 | Link |
Soul Architect
Join Date: Apr 2014
Posts: 2,559
|
The conversation is kind of split in-between this thread and the Shaders thread. Anyway.
This can *definitely* be done. http://www.avisynth.nl/index.php/Fil...nge_frame_size All you need is to resize your frame buffer. Basically, to go from pixels of 2 bytes to pixels of 16 bytes, you need to create a new frame with the width * 8. Then it's up to you how you store the data. Make one pass through the source video to copy YUY2 to float RGB 2 pixels at a time. Then make a second pass in that same frame to replace each RGB pixel data with Lab pixel data. Voila! The only downside is that AviSynth won't recognize that frame type and it won't be a valid output, so you just need to know it's in that format and convert it back into a valid display format afterwards. This can definitely be done, calling shaders can definitely be done, and passing float RGBA (or float Lab) data from one filter to another in a clip can also be done. It just needs to be put together. I believe planar is mostly useful when working with individual planes without needing the other planes? The work in shaders is done pixel per pixel so I don't think planes should be used here.
__________________
FrameRateConverter | AvisynthShader | AvsFilterNet | Natural Grounding Player with Yin Media Encoder, 432hz Player, Powerliminals Player and Audio Video Muxer Last edited by MysteryX; 8th July 2015 at 02:41. |
8th July 2015, 08:11 | #12 | Link | |
Soul Architect
Join Date: Apr 2014
Posts: 2,559
|
Before talking about Lab, we first have to look at converting YUV to float RGB back and forth.
Wikipedia says this: Quote:
inline void YUV2RGB(int y, int u, int v, BYTE* out) { const int crv = int(1.596*65536+0.5); const int cgv = int(0.813*65536+0.5); const int cgu = int(0.391*65536+0.5); const int cbu = int(2.018*65536+0.5); int scaled_y = (y - 16) * int((255.0/219.0)*65536+0.5); out[0] = ScaledPixelClip(scaled_y + (u-128) * cbu); // blue out[1] = ScaledPixelClip(scaled_y - (u-128) * cgu - (v-128) * cgv); // green out[2] = ScaledPixelClip(scaled_y + (v-128) * crv); // red } inline int RGB2YUV(int rgb) { const int cyb = int(0.114*219/255*65536+0.5); const int cyg = int(0.587*219/255*65536+0.5); const int cyr = int(0.299*219/255*65536+0.5); // y can't overflow int y = (cyb*(rgb&255) + cyg*((rgb>>8)&255) + cyr*((rgb>>16)&255) + 0x108000) >> 16; int scaled_y = (y - 16) * int(255.0/219.0*65536+0.5); int b_y = ((rgb&255) << 16) - scaled_y; int u = ScaledPixelClip((b_y >> 10) * int(1/2.018*1024+0.5) + 0x800000); int r_y = (rgb & 0xFF0000) - scaled_y; int v = ScaledPixelClip((r_y >> 10) * int(1/1.596*1024+0.5) + 0x800000); return ((y*256+u)*256+v) | (rgb & 0xff000000); } |
|
9th July 2015, 03:56 | #13 | Link |
Soul Architect
Join Date: Apr 2014
Posts: 2,559
|
This is the best answer about color conversion
http://www.fourcc.org/fccyvrgb.php |
Thread Tools | Search this Thread |
Display Modes | |
|
|