Log in

View Full Version : gamut conversions through Avisynth ?


Pages : 1 2 3 4 [5] 6 7 8 9 10 11 12 13 14 15

madshi
6th February 2009, 16:55
You should consider the actual readme as the technical readme.;)
Ok, that readme is probably very good then... :)

I'm not so sure about this. I was thinking that maybe could be a good idea of allowing the 3D LUT to work both ways:
YCbCr->RGB or RGB->YCbCr.
tritical, what do you think about it? Some people are reporting slightly better results when performing YCbCr->RGB with the 3D LUT, maybe the RGB->YCbCr could also be more accurate with the 3D LUT?
I think that would be a good idea starting a new thread about rgb3dlut. Now, there is a new option available for the Avisynth usage (using 3D LUTs), and the current thread name is not very meaningfull about it; some potential users could be missing it...
If you agree with using the 3dlut in both ways, we have two optios:
-rename rgb3dlut to a more generic name
-keep rgb3dlut as it is and create ycbcr3dlut or yuv3dlut (i prefer the former because is the correct designation), etc. As you wish.
Well, if you go that way then you may also want to support YCbCr -> YCbCr. Also you may want to support RGB computer levels -> RGB video levels. In any case, if the options are not clear about whether they're supposed to affect input or output, there can be all kinds of misunderstandings. Just think about the ffdshow RGB controls which were backwards (are finally fixed) and about Haali's RGB levels control, which is also backwards. It's all because the options don't clearly say whether they're meant to control input or output levels. If you want to do RGB -> RGB then you probably have to offer RGB_BW options for both input and output. And if you want to support YCbCr -> YCbCr you probably have to offer full_range options for both input and output. So IMHO the options should be clearly separated for input and output.

yesgrey
6th February 2009, 17:09
So IMHO the options should be clearly separated for input and output.
Yes, you're right. I will change it for the next version.
Thanks

tritical
6th February 2009, 20:38
v1.9 should fix the speed issues... it was the compiler sucking at inlining some functions. Also, when I was explaining yv12toyuy2 vs converttoyuy2 I forgot to mention that converttoyuy2 is significantly faster (it has mmx/isse versions, whereas yv12toyuy2 is just written in c). So unless you really need the extra functionality of yv12toyuy2 I would recommend using converttoyuy2. I wrote yv12toyuy2 mainly for comparison purposes.

@yesgrey3
Adding rgb->yuy2, yuy2->yuy2, and yv12->yv12 support is a good idea. I would probably just rename rgb3dlut to 3dlut, and move it to its own dll at that point.

leeperry
6th February 2009, 20:46
v1.9 should fix the speed issues... it was the compiler sucking at inlining some functions.
indeed! on an o/c Q6600 :

ddcc 1.7

yv12toyuy2(itype=1,threads=4)
=1400 fps

rgb3dlut(lutfile="C:\BT709_16-235.txt",itype=2,threads=4)
=622 fps

ddcc 1.9

yv12toyuy2(itype=1,threads=4)
=1410 fps

rgb3dlut(lutfile="C:\BT709_16-235.txt",itype=2,threads=4)
=700 fps

OK now yv12toyuy2() doesn't crash if it's not mod4, it simply gives an error msg.
is there any potentially visible improvement using yv12toyuy2(itype=0) over ConvertToYUY2() ? or if you don't mind forcing it to use 0 if it's not mod4 :thanks:

yesgrey
6th February 2009, 23:48
Adding yuy2->yuy2, and yv12->yv12
What's the idea of this, changing the luma matrix coefficients and/or levels?
Please tell me when you are thinking in adding that, so I can set my priorities for cr3dlut development...;)
I would probably just rename rgb3dlut to 3dlut, and move it to its own dll at that point.
Yes, and perhaps it would also be the time for starting a new thread about it...
Can a function name start with a number? I think that would be the best name, but i thought that it was not possible...

yesgrey
6th February 2009, 23:57
(13) I'd like to have an option to output 16bit RGB instead of 8bit... ;)
This would be very simple to add, but completelly useless for now... You will need a video renderer that supports 16bit per component, and Avisynth also only supports 8bit per component. I've read something about Avisynth 3.0 supporting RGB45 (15bit per component), but I don't know if it's still being developed.
I also need to know the format of the 3D LUT. I could simply use the current format just changing the offset considering 16bit instead of 8bit, but I don't know if that would be the desired format...
I think you will have to wait a little more. For cr3dlut, it will be less than a day of work, but all the other stuff that we need could take a little bit longer...:(

leeperry
7th February 2009, 01:03
ah...yv12toyuy2(itype=0) used to work w/ non-mod4, but now it also gives an error msg....back to ConvertToYUY2() :o

madshi
7th February 2009, 12:46
This would be very simple to add, but completelly useless for now... You will need a video renderer that supports 16bit per component, and Avisynth also only supports 8bit per component. I've read something about Avisynth 3.0 supporting RGB45 (15bit per component), but I don't know if it's still being developed.
I also need to know the format of the 3D LUT. I could simply use the current format just changing the offset considering 16bit instead of 8bit, but I don't know if that would be the desired format...
I think you will have to wait a little more. For cr3dlut, it will be less than a day of work, but all the other stuff that we need could take a little bit longer...:(
Here comes my suggestion:

The 3dlut files *have* to get a header. The header should contain at least the following information:

(1) signature, e.g. "3dlut"
(2) header size
(3) file format version number
(4) program which created this file (e.g. "cr3dlut")
(5) version of the program which created this file (Windows version information "a.b.c.d" = 4 words)
(6) input color space (RGB or YUY2 something else)
(7) output color space (YUY2 or YCbCr or something else)
(8) input bitdepth (8bit or 16bit) - even if 16bit input doesn't seem to make sense right now
(9) output bitdepth (8bit or 16bit)
(10) detailed list of *every single* parameter used to create the file
(11) maybe some reserved fields for future use

The file format should never break. In the worst case a new "file format version number" could be used, e.g. if you added support for display primaries for different luminance levels or things like that. If you can create a file format which is already fit for all future extensions you plan to do that would be awesome, of course...

Let's just imagine someone decided to create a DirectShow filter doing gamut correction based on your 3dlut solution. That DirectShow filter should be able to find out whether a specific 3dlut file has the expected format. If it does not, the filter could just delete it and recreate it on the fly by using cr3dlut. The filter could offer the consumer a list of controls (e.g. display gamma and primaries) and further options like RGB output levels (video or computer) etc. The necessary 3dlut files could always be created on the fly before video playback is started. But such a logic would definitely require a clearly defined header for the 3dlut files. Finally, such a DirectShow filter could easily make use of 16bit RGB output, e.g. to feed a potential new Windows 7 16bit RGB renderer or to dither down the 16bit RGB 3dlut output to any desired RGB bitdepth. Saying that AviSynth doesn't support more than 8bit RGB yet and that there's no renderer for 16bit RGB yet feels a bit short sighted to me. Maybe Haali would be motivated to update his renderer to support Windows 7 16bit if there was a ready to use gamut correction solution outputting 16bit RGB? He won't add 16bit output if there's no argument for it, obviously. So *please* let's not play the chicken and egg game.

I think if you guys provided the necessary framework with exact specifications, that might increase motivation for other programmers to jump in and provide the missing pieces of the puzzle. Saying: "Maybe we will add this later" and "I don't know how the file format of 16bit output would look like" etc makes all your work feel like "it's not ready to be used by other programmers yet". That is likely to slow down adoption by other programmers...

IMHO the first thing you should do is create a file format for 3dlut. The 2nd thing to do would be to make cr3lut create files in that format. That would be the minimum needed for other programmers to jump in and make use of it, I think.

yesgrey
7th February 2009, 14:52
Here comes my suggestion:
The 3dlut files *have* to get a header.
That's a very good suggestion, because with all the possible options that could be added to the 3dlut it would be very hard to know which will do what... I will start working on it.
The file format should never break...
If you can create a file format which is already fit for all future extensions you plan to do that would be awesome, of course...

For a 3dlut this is easy. The output will always be the same for the same output bit depths. For example, for the current 8bit version, the output will always be an array of 3x[256,256,256] 1 byte entries. What could change is just the way the output values are computed, nothing more.
So *please* let's not play the chicken and egg game.
Ok, I will put the egg.:D
I will add 16bit and possibly other output bit depths.
Let's hope he grows in a beautiful chicken...;)

@tritical,
I will start the specification of a header for the 3dlut files, based on madshi suggestions. For the 3d lut files with 16bit output are you ok with this format:
offset: ((v<<16)+(u<<8)+y)*3 2 bytes entries
offset: ((g<<16)+(b<<8)+r)*3 2 bytes entries
At that location, the associated rgb value should be stored in b, g, r order.
Would it be better considering only 8bit and 16bit output? It would be easier to code... what about performance wise?
With all the options we are considering for rgb3dlut, maybe it would also be better start using some kind of compression with the lut files. If we need to have several in our computer it will consume some hard disk space... any suggestion?

FoLLgoTT
7th February 2009, 18:37
There is a 10 bit per component mode in DirectShow called MEDIASUBTYPE_A2R10G10B10 (http://msdn.microsoft.com/en-us/library/dd407253(VS.85).aspx). Is it somehow possible to use that mode with VMR9 or other Renderers?

While searching a time ago I found nearly nothing about displaying graphics with more than 8 bit per component on Windows platform.

yesgrey
7th February 2009, 21:31
There is a 10 bit per component mode in DirectShow called MEDIASUBTYPE_A2R10G10B10 (http://msdn.microsoft.com/en-us/library/dd407253(VS.85).aspx). Is it somehow possible to use that mode with VMR9 or other Renderers?
With VMR9 I don't think so, in the Video Mixing Renderer Subtypes (http://msdn.microsoft.com/en-us/library/dd407345(VS.85).aspx) it doesn't appear... With another renderers, I don't know.
While searching a time ago I found nearly nothing about displaying graphics with more than 8 bit per component on Windows platform.
Apparently only Windows7 will allow it.
I have read a user report in this forum that when using a 10bit lcd monitor with dvi connection the current windows version would show a 10bit per component graphic mode, but I don't know if it's true.

madshi
7th February 2009, 23:28
For a 3dlut this is easy. The output will always be the same for the same output bit depths. For example, for the current 8bit version, the output will always be an array of 3x[256,256,256] 1 byte entries. What could change is just the way the output values are computed, nothing more.
True for the data array. But how about the header? I would really want to have all the parameters in the header which were used to create the 3dlut data array. So if the parameter logic changes, the header might have to change, too. E.g. currently users can define only one set of primaries for the display, IIRC. Maybe some day you will allow primaries for different luminance levels. If you do that, the header may have to change, if you really want to put all the parameters in there which were used to create the 3dlut file.

Or maybe you could simply store the cr3dlut config text file in the header which was used to create the 3dlut file?

Ok, I will put the egg.:D
Great - thanks!!

I will add 16bit and possibly other output bit depths.
What other output bit depths would make sense? Maybe 8bit and 16bit is all we need? More than 16bit should be overkill. And any intermediate value between 8bit and 16bit could easily be calculated on the fly by the software (e.g. DirectShow filter) which does all the work. If I were to design a software (e.g. DirectShow filter) which "executes" gamut correction based on 3dlut I'd probably not even use 8bit 3dlut files at all. I'd only use 16bit 3dlut and then dither down to 8bit, if needed. I wouldn't really care much if that costs a few percent of performance...

yesgrey
8th February 2009, 00:58
Or maybe you could simply store the cr3dlut config text file in the header which was used to create the 3dlut file?
Yes, I think this would be the best. If we'll edit the 3dlut file with a text editor we could see the run parameters settings, and it will be a small overhead...
What other output bit depths would make sense?
Well, for people who doesn't want to use dithering, it would be better having it in the display's native bit depth.
More than 16bit should be overkill.
16bit is already overkill...;)

yesgrey
8th February 2009, 01:55
Here is the first iteration for the definition of a file format for the 3D LUT:
struct
{
char sig[6];
int size, ver, biti, bito, cci, cco;
char pname[20];
int pver, sizerp, reserv1, reserv2;
} h3dlut;

/* 3D LUT file specification:

// Header
sig - File signature, must be: '3DLUT'
size - File header size in bytes
ver - File format version number
biti - Input bit depth per component (same for all three)
bito - Output bit depth per component (same for all three)
cci - Input color coding
0 - R'G'B'
> 0 - Y'Cb'Cr' - index to luma_matrix_coeffs
cco - Output color coding
0 - R'G'B'
> 0 - Y'Cb'Cr' - index to luma_matrix_coeffs
pname - Name of the program that created the file
pver - Version of the program that created the file
sizerp - Size in bytes of the array of char with a copy of the
run parameters settings used for creating the file
reserv1 - Reserved for future usage
reserv2 - Reserved for future usage

// Parameters Settings
sizerp bytes

// Data
3*((2^biti)^3)*bito/8 bytes
This is the general formula, in reality it's only usable the biti=8 version
*/
Any suggestions/corrections are welcome.
@tritical,
If you agree, let me know so I can implement it and release the first version of the 3DLUT file format.

cyberbeing
8th February 2009, 09:10
Would there be any quality advantage of completely bypassing the video card LUT (i.e. leaving your 8bit display uncalibrated) and applying your calibrated gamma ramp instead through 3dlut before it does its other adjustments?

My limited understanding is, considering that most graphics cards only have a 8bit or 10bit LUT, doing the adjustment with 3dlut which is 16bit would result in less banding. Is this correct?

If so, could support for applying a calibrated gamma ramp (using something like the values exported from CalibrationTester) before the CMS compensations are done be added?

leeperry
8th February 2009, 10:56
Would there be any quality advantage of completely bypassing the video card LUT (i.e. leaving your 8bit display uncalibrated) and applying your calibrated gamma ramp instead through 3dlut before it does its other adjustments?

My limited understanding is, considering that most graphics cards only have a 8bit or 10bit LUT, doing the adjustment with 3dlut which is 16bit would result in less banding. Is this correct?

If so, could support for applying a calibrated gamma ramp (using something like the values exported from CalibrationTester) before the CMS compensations are done be added?
good point, even though I'm dubious about any banding improvement?!
ARGYLLCMS outputs this sort of 1D LUT for calibration :
NUMBER_OF_SETS 256
BEGIN_DATA
0.0000 0.083189 0.021229 0.023934
3.9216e-003 0.087305 0.047484 0.028051
7.8431e-003 0.091516 0.061404 0.032320
0.011765 0.095825 0.071292 0.036751
0.015686 0.10023 0.079941 0.041354
0.019608 0.10475 0.088256 0.046137
0.023529 0.10937 0.096318 0.051114
0.027451 0.11409 0.10400 0.056294
0.031373 0.11882 0.11121 0.061668
0.035294 0.12350 0.11782 0.067159
0.039216 0.12807 0.12387 0.072689
0.043137 0.13247 0.12948 0.078181
0.047059 0.13671 0.13473 0.083563
0.050980 0.14080 0.13966 0.088789
0.054902 0.14475 0.14437 0.093852
0.058824 0.14860 0.14889 0.098760
0.062745 0.15235 0.15323 0.10354
0.066667 0.15601 0.15747 0.10823
0.070588 0.15960 0.16162 0.11283
0.074510 0.16315 0.16566 0.11736
0.078431 0.16664 0.16961 0.12183
0.082353 0.17010 0.17345 0.12626
0.086275 0.17353 0.17722 0.13063
0.090196 0.17695 0.18092 0.13497
0.094118 0.18034 0.18457 0.13927
0.098039 0.18369 0.18818 0.14352
0.10196 0.18701 0.19175 0.14771
0.10588 0.19030 0.19534 0.15185
0.10980 0.19355 0.19889 0.15593
0.11373 0.19679 0.20245 0.15996
0.11765 0.20002 0.20604 0.16396
0.12157 0.20324 0.20968 0.16794
0.12549 0.20647 0.21337 0.17190
0.12941 0.20970 0.21707 0.17586
0.13333 0.21293 0.22077 0.17980
0.13725 0.21616 0.22444 0.18373
0.14118 0.21938 0.22807 0.18765
0.14510 0.22257 0.23167 0.19155
0.14902 0.22575 0.23524 0.19542
0.15294 0.22891 0.23872 0.19925
0.15686 0.23207 0.24214 0.20306
0.16078 0.23521 0.24550 0.20685
0.16471 0.23833 0.24883 0.21061
0.16863 0.24143 0.25216 0.21436
0.17255 0.24450 0.25548 0.21808
0.17647 0.24758 0.25880 0.22179
0.18039 0.25068 0.26216 0.22546
0.18431 0.25379 0.26554 0.22912
0.18824 0.25693 0.26891 0.23277
0.19216 0.26008 0.27230 0.23641
0.19608 0.26324 0.27569 0.24003
0.20000 0.26642 0.27910 0.24366
0.20392 0.26961 0.28251 0.24731
0.20784 0.27282 0.28593 0.25096
0.21176 0.27602 0.28935 0.25463
0.21569 0.27921 0.29280 0.25832
0.21961 0.28238 0.29625 0.26200
0.22353 0.28554 0.29964 0.26570
0.22745 0.28867 0.30297 0.26940
0.23137 0.29177 0.30625 0.27309
0.23529 0.29482 0.30950 0.27678
0.23922 0.29783 0.31273 0.28045
0.24314 0.30081 0.31594 0.28412
0.24706 0.30375 0.31910 0.28778
0.25098 0.30666 0.32227 0.29146
0.25490 0.30954 0.32544 0.29513
0.25882 0.31239 0.32864 0.29879
0.26275 0.31521 0.33185 0.30242
0.26667 0.31801 0.33510 0.30606
0.27059 0.32080 0.33837 0.30971
0.27451 0.32357 0.34171 0.31334
0.27843 0.32633 0.34507 0.31698
0.28235 0.32909 0.34844 0.32062
0.28627 0.33184 0.35180 0.32425
0.29020 0.33460 0.35515 0.32787
0.29412 0.33736 0.35850 0.33149
0.29804 0.34013 0.36182 0.33510
0.30196 0.34292 0.36512 0.33870
0.30588 0.34573 0.36840 0.34229
0.30980 0.34856 0.37163 0.34587
0.31373 0.35141 0.37483 0.34944
0.31765 0.35430 0.37801 0.35302
0.32157 0.35723 0.38120 0.35660
0.32549 0.36019 0.38439 0.36018
0.32941 0.36319 0.38759 0.36376
0.33333 0.36622 0.39079 0.36735
0.33725 0.36926 0.39400 0.37095
0.34118 0.37232 0.39727 0.37455
0.34510 0.37539 0.40062 0.37815
0.34902 0.37847 0.40404 0.38178
0.35294 0.38152 0.40742 0.38542
0.35686 0.38457 0.41073 0.38906
0.36078 0.38759 0.41400 0.39271
0.36471 0.39061 0.41727 0.39636
0.36863 0.39361 0.42054 0.40003
0.37255 0.39661 0.42379 0.40371
0.37647 0.39957 0.42703 0.40738
0.38039 0.40251 0.43029 0.41101
0.38431 0.40542 0.43356 0.41463
0.38824 0.40834 0.43686 0.41826
0.39216 0.41125 0.44017 0.42191
0.39608 0.41415 0.44352 0.42554
0.40000 0.41704 0.44689 0.42916
0.40392 0.41992 0.45025 0.43277
0.40784 0.42281 0.45363 0.43636
0.41176 0.42569 0.45704 0.43995
0.41569 0.42858 0.46047 0.44353
0.41961 0.43148 0.46390 0.44712
0.42353 0.43438 0.46733 0.45071
0.42745 0.43729 0.47076 0.45430
0.43137 0.44021 0.47416 0.45790
0.43529 0.44316 0.47755 0.46154
0.43922 0.44611 0.48092 0.46519
0.44314 0.44907 0.48427 0.46886
0.44706 0.45203 0.48760 0.47255
0.45098 0.45500 0.49092 0.47624
0.45490 0.45800 0.49422 0.47994
0.45882 0.46104 0.49752 0.48364
0.46275 0.46410 0.50088 0.48734
0.46667 0.46717 0.50426 0.49102
0.47059 0.47023 0.50763 0.49470
0.47451 0.47329 0.51097 0.49837
0.47843 0.47633 0.51429 0.50204
0.48235 0.47937 0.51760 0.50570
0.48627 0.48239 0.52091 0.50936
0.49020 0.48540 0.52423 0.51301
0.49412 0.48838 0.52756 0.51662
0.49804 0.49131 0.53090 0.52021
0.50196 0.49420 0.53424 0.52377
0.50588 0.49704 0.53761 0.52730
0.50980 0.49984 0.54101 0.53079
0.51373 0.50260 0.54441 0.53426
0.51765 0.50535 0.54780 0.53770
0.52157 0.50809 0.55119 0.54112
0.52549 0.51083 0.55459 0.54452
0.52941 0.51358 0.55797 0.54792
0.53333 0.51637 0.56136 0.55132
0.53725 0.51917 0.56478 0.55473
0.54118 0.52201 0.56821 0.55817
0.54510 0.52486 0.57156 0.56162
0.54902 0.52773 0.57486 0.56510
0.55294 0.53063 0.57815 0.56863
0.55686 0.53355 0.58143 0.57219
0.56078 0.53649 0.58470 0.57579
0.56471 0.53943 0.58796 0.57941
0.56863 0.54237 0.59122 0.58308
0.57255 0.54532 0.59449 0.58680
0.57647 0.54827 0.59776 0.59054
0.58039 0.55119 0.60104 0.59430
0.58431 0.55408 0.60432 0.59807
0.58824 0.55695 0.60763 0.60185
0.59216 0.55978 0.61094 0.60565
0.59608 0.56259 0.61424 0.60945
0.60000 0.56539 0.61753 0.61327
0.60392 0.56820 0.62085 0.61709
0.60784 0.57102 0.62419 0.62091
0.61176 0.57386 0.62754 0.62471
0.61569 0.57671 0.63089 0.62851
0.61961 0.57960 0.63422 0.63229
0.62353 0.58252 0.63753 0.63606
0.62745 0.58548 0.64084 0.63981
0.63137 0.58849 0.64420 0.64354
0.63529 0.59153 0.64767 0.64726
0.63922 0.59461 0.65129 0.65096
0.64314 0.59772 0.65505 0.65466
0.64706 0.60087 0.65889 0.65832
0.65098 0.60405 0.66261 0.66193
0.65490 0.60723 0.66619 0.66547
0.65882 0.61039 0.66964 0.66895
0.66275 0.61351 0.67301 0.67239
0.66667 0.61660 0.67637 0.67586
0.67059 0.61968 0.67973 0.67937
0.67451 0.62277 0.68309 0.68291
0.67843 0.62587 0.68643 0.68648
0.68235 0.62898 0.68974 0.69004
0.68627 0.63209 0.69302 0.69359
0.69020 0.63519 0.69628 0.69712
0.69412 0.63827 0.69951 0.70066
0.69804 0.64136 0.70272 0.70421
0.70196 0.64446 0.70594 0.70777
0.70588 0.64758 0.70915 0.71135
0.70980 0.65070 0.71237 0.71493
0.71373 0.65383 0.71561 0.71852
0.71765 0.65695 0.71883 0.72214
0.72157 0.66009 0.72207 0.72578
0.72549 0.66323 0.72529 0.72943
0.72941 0.66636 0.72850 0.73310
0.73333 0.66948 0.73172 0.73678
0.73725 0.67259 0.73496 0.74048
0.74118 0.67569 0.73824 0.74418
0.74510 0.67880 0.74155 0.74790
0.74902 0.68191 0.74488 0.75164
0.75294 0.68502 0.74823 0.75539
0.75686 0.68812 0.75159 0.75914
0.76078 0.69120 0.75499 0.76290
0.76471 0.69427 0.75840 0.76668
0.76863 0.69734 0.76185 0.77046
0.77255 0.70040 0.76535 0.77424
0.77647 0.70346 0.76888 0.77803
0.78039 0.70653 0.77243 0.78182
0.78431 0.70960 0.77603 0.78563
0.78824 0.71269 0.77971 0.78946
0.79216 0.71580 0.78351 0.79329
0.79608 0.71890 0.78727 0.79712
0.80000 0.72198 0.79095 0.80093
0.80392 0.72505 0.79458 0.80476
0.80784 0.72814 0.79821 0.80863
0.81176 0.73124 0.80183 0.81250
0.81569 0.73433 0.80544 0.81638
0.81961 0.73743 0.80903 0.82027
0.82353 0.74054 0.81259 0.82416
0.82745 0.74367 0.81613 0.82806
0.83137 0.74680 0.81968 0.83195
0.83529 0.74994 0.82325 0.83583
0.83922 0.75307 0.82684 0.83970
0.84314 0.75619 0.83043 0.84356
0.84706 0.75930 0.83406 0.84741
0.85098 0.76242 0.83776 0.85126
0.85490 0.76555 0.84142 0.85511
0.85882 0.76867 0.84502 0.85896
0.86275 0.77178 0.84862 0.86283
0.86667 0.77489 0.85219 0.86669
0.87059 0.77799 0.85573 0.87054
0.87451 0.78109 0.85927 0.87438
0.87843 0.78420 0.86280 0.87821
0.88235 0.78733 0.86635 0.88202
0.88627 0.79048 0.86992 0.88581
0.89020 0.79364 0.87344 0.88959
0.89412 0.79680 0.87696 0.89338
0.89804 0.79998 0.88047 0.89716
0.90196 0.80316 0.88399 0.90093
0.90588 0.80634 0.88752 0.90468
0.90980 0.80953 0.89105 0.90842
0.91373 0.81271 0.89456 0.91217
0.91765 0.81589 0.89809 0.91591
0.92157 0.81906 0.90164 0.91964
0.92549 0.82222 0.90518 0.92335
0.92941 0.82538 0.90873 0.92704
0.93333 0.82854 0.91228 0.93072
0.93725 0.83169 0.91582 0.93440
0.94118 0.83484 0.91938 0.93809
0.94510 0.83801 0.92293 0.94178
0.94902 0.84119 0.92647 0.94547
0.95294 0.84438 0.93002 0.94916
0.95686 0.84757 0.93356 0.95285
0.96078 0.85077 0.93710 0.95654
0.96471 0.85398 0.94065 0.96023
0.96863 0.85720 0.94419 0.96392
0.97255 0.86041 0.94773 0.96760
0.97647 0.86363 0.95128 0.97127
0.98039 0.86683 0.95483 0.97493
0.98431 0.87004 0.95838 0.97858
0.98824 0.87324 0.96194 0.98222
0.99216 0.87643 0.96550 0.98586
0.99608 0.87962 0.96907 0.98948
1.0000 0.88281 0.97263 0.99310
END_DATA
CAL
its author is all for GPL, and very helpful if needed.
but this graphic card 1D LUT is also used on the desktop, so you get D65 calibration in picture viewers and games....plus this is done in 10 bits, ARGYLLCMS has a tool to check the LUT accuracy.
considering the TMDS of the HDMI/DVI outputs will be encoded in RGB24 anyhow, and that the 3D LUT computing is done in 64bit floating point per component, I don't see it getting any more accurate and show *VISIBLE* improvement :o

yesgrey
8th February 2009, 12:13
Would there be any quality advantage of completely bypassing the video card LUT (i.e. leaving your 8bit display uncalibrated) and applying your calibrated gamma ramp instead through 3dlut before it does its other adjustments?
IMHO for video it would be like this:
-3D LUT 8bit and GC LUT 8bit: do all processing in 3D LUT
-3D LUT 8bit and GC LUT 10bit: do all processing in 3D LUT except gamma correction to fit displays gamma, this should be done in the GC LUT, which has higher accuracy
-3D LUT 16bit dithered to 8bit: do all processing in 3D LUT.
The last option is not available, and I don't know if it will ever be.
If so, could support for applying a calibrated gamma ramp (using something like the values exported from CalibrationTester) before the CMS compensations are done be added?
This is part of my plans, but in fact the gamma correction would be part of the CMS, the last step. I'm already working on it, but I'm waiting feedback about the 3DLUT file format specification.

yesgrey
8th February 2009, 12:20
but this graphic card 1D LUT is also used on the desktop, so you get D65 calibration in picture viewers and games....
Yes. The 3D LUT we are talking about only could be used for videos and photos, if you use a program that uses it (currently only an avisynth scrip directly or via ffdshow support). For the desktop, you are better with the GC 1D LUT.

leeperry
8th February 2009, 12:24
Yes. The 3D LUT we are talking about only could be used for videos and photos, if you use a program that uses it (currently only an avisynth scrip directly or via ffdshow support). For the desktop, you are better with the GC 1D LUT.
well we could use the GC 1D LUT for the desktop, and OVERLAY for videos(as it doesn't care for the GC LUT) but :
-I don't wanna use Overlay, HR is far smoother and free of video drivers sharpening blabla
-the GC LUT is 10 bits, it won't create more banding than needed by the calibration IMHO

BTW I'm being lazy as my gamut config works perfectly fine as it is, just that I have to use one YUY2 LUT for RGB conversion + one RGB LUT for gamut conversion....I will try to look into creating an all-in-one LUT w/ your app later today :p

cyberbeing
8th February 2009, 13:09
3D LUT 16bit dithered to 8bit: do all processing in 3D LUT.
The last option is not available, and I don't know if it will ever be.

That last option is what I was thinking of. What is the reason against implementing this? Would it be too slow? I was under the assumption that rgb3dlut already had this capability and all it would need was a specially created lut file to do this.

leeperry
8th February 2009, 13:12
That last option is what I was thinking of. What is the reason against implementing this? Would it be too slow?
the LUT would be HUGE, and the visible improvement inexistent? it's already done in 64 bits float, and you're gonna have to wait forever before display drivers actually support 10 bits.

OTOH maybe 10 bits could be implement for futureproof sake's?

yesgrey
8th February 2009, 14:28
That last option is what I was thinking of. What is the reason against implementing this? Would it be too slow? I was under the assumption that rgb3dlut already had this capability and all it would need was a specially created lut file to do this.
I will add the 16 bit output 3D LUT very soon, so it will only depends if tritical would want to add dithering to 8bits in rgb3dlut. It will be slower than without dithering, but essentially it will depend on the dither algorythm used... Floyd-Steinberg could be the best balance between quality and speed. From the dithering wiki-page (http://en.wikipedia.org/wiki/Dithering) the stucki method looks the best for me, but probably it would be too slow and/or too complicated to add...
the LUT would be HUGE
The LUT would be HUGE for 16 bit input. For 8bit input/16 bit output it will be 96MB, still pretty usable...
it's already done in 64 bits float
That's the internal computing resolution, the output resolution will always be a limiting factor...;)
So it should be: "16 bit" better than "16bit dithered to 8bit" better than "8bit".

leeperry
8th February 2009, 14:40
the output resolution will always be a limiting factor
true, but all we got now is RGB24 TMDS anyhow.
maybe in a few years if we've not been naughty, we'll get 10 bits...so adding 10 bits/10 bits dither would be more useful IMHO.

of course we'll have to buy spanking new HDMI 1.3 displays.....personally I've never seen any banding using your algorithms in 8 bits, so I'm not too worried :cool:

and before we get >8 bits native video sources, it will take a LONG while.

cyberbeing
8th February 2009, 14:57
so it will only depends if tritical would want to add dithering to 8bits in rgb3dlut.
You heard the man, so tritical, any interest in adding 16bit-->8bit dithering in rgb3dlut?


the LUT would be HUGE
The LUT would be HUGE for 16 bit input. For 8bit input/16 bit output it will be 96MB, still pretty usable...
Photoshop does all processing with 16bit per component and 128bit floating point precision via lut tables. Out of curiosity how do you assume Photoshop does this without taking up massive diskspace or memory with 16bit and 32bit input images?

Is there some better alternative method which is being overlooked? Do you think Photoshop generates a partial lut table wherever needed, on the fly? Something else? Too slow for your uses?

leeperry
8th February 2009, 15:05
Photoshop does all processing with 16bit per component and 128bit floating point precision via lut tables.
I demand 1024bit accuracy :p j/k ;)

pshop uses ICC v4 files for softproofing AFAIK

cyberbeing
8th February 2009, 15:18
I demand 1024bit accuracy :p j/k ;)
Duotriguple Precision??? :scared:


pshop uses ICC v4 files for softproofing AFAIK

If that is the case, and it somehow makes the situation better, why aren't we using 16bit ICC profiles in ddcc?

tetsuo55
8th February 2009, 15:49
Awesome news.

Just want to add view.

-The default Lut's should be 16bit per component, lower bits are optional(for slower systems)
-All internal processing should be 64bit or higher
-The should be a choice between dithering:none, fast, balanced, slow (increasing in quality over speed)
-The output bitdepth should be selectable: 6,8,10,12,16(I'm not sure if 6bit is possible and if it helps those 6bit lcd panels at all)


Once this all works we will need a proof of concept.

-A player that supports 16bit
-A renderer that supports 16bit
-A 16bit sample

Once we have all this in place we can start demanding support (the egg is in place)

-Write all the videocard developers that we want:
*10/12/16bit per component output support
*HDMI1.3C on their videocards
*We want updated drivers supporting this for current hardware

-Write all videocard reseller brands(like asus, msi) the same email.
-Write all display manufacturers the same letter:
*16 bit and lower per componenent input
*Native 16 panels
*Driver updates for current 10/12 bit panels

-File support tickets with the oem companies that you cannot use this 16bit setup because the system they sold you does not support it :(
-Ask the oem companies for 16bit capable hardware and get dissapointed for them not selling it

We might have to push Micrsoft too..

PS.

i know there is no commercial >8 bit content at this time. Maybe a big wave like the one above can spark more interest

yesgrey
8th February 2009, 17:48
before we get >8 bits native video sources, it will take a LONG while.
For >8bit sources the 3DLUT will not be usable...
Input/output: 3D LUT size
8bit/8bit: 48MB
8bit/16bit: 96MB
9bit/9bit: 432MB
10bit/10bit: 3840MB
But since the sources should being kept at 8bit...

You heard the man, so tritical, any interest in adding 16bit-->8bit dithering in rgb3dlut?

It doesn't have to be tritical doing it... the source code is available, so anyone who wishes to can do it. But I think it would be better tritical doing it... let's hope he agrees with it and have the time for it.;)

Photoshop does all processing with 16bit per component and 128bit floating point precision via lut tables. Out of curiosity how do you assume Photoshop does this without taking up massive diskspace or memory with 16bit and 32bit input images?
Photoshop should be using the lut only for the gamma correction, and for that we only need 1D LUTs - each component only depends on itself.
The size formula for 3 1D LUT is: 3*(2^biti)*bito/8 bytes
So, for a 16bit in/16bit out the size is only: 384kB

why aren't we using 16bit ICC profiles in ddcc?
Because the ICC profiles should be used at the software player renderer level.

-All internal processing should be 64bit or higher
No need for higher than 64bit FP. I have tryed 80bit FP and the results were exactly the same, only 15% slower in the computation.
I have also tryed 32bit FP, but with that was a slightly difference against 64bit. Some values differ of +/- 1. Nothing visually noticeable, but since we are performing the computation offline there is no reason to get less accurate results.
-The should be a choice between dithering:none, fast, balanced, slow (increasing in quality over speed)
I think it would be good enough just a basic algorythm like Floyd-steinberg or Sierra-lite (I think this is preferable, since it's the same visual quality as floyd and a little less cpu intensive). Even without dithering we aren't noticing any banding, so let's keep this simple.
I'm not sure if 6bit is possible and if it helps those 6bit lcd panels at all
It's possible, but it would be useless. The 6bit lcd panels perform their own dithering from an 8bit input for their native 6bit.
Once we have all this in place we can start demanding support (the egg is in place)
A massive attack!!!:D

leeperry
8th February 2009, 18:07
Photoshop should be using the lut only for the gamma correction, and for that we only need 1D LUTs - each component only depends on itself.
The size formula for 3 1D LUT is: 3*(2^biti)*bito/8 bytes
So, for a 16bit in/16bit out the size is only: 384kB
apparently you can have 3D LUT's within ICC v4 profiles.
I played around w/ them in X-Rite Profile Maker 5, too bad they only work in color managed apps(pshop, firefox, etc..)
pshop can do full gamut conversions w/ its softproofing options apparently.
but going ICC v4 in rgb3dlut would be pointless, as this is not even an open standard I think? not sure

madshi
8th February 2009, 19:27
sig - File signature, must be: '3DLUT'
'3DLUT' are only 5 chars. So maybe the definition should be "char sig[5]"?

int size, ver, biti, bito, cci, cco;
char pname[20];
int pver, sizerp, reserv1, reserv2;
I'd prefer much much MUCH longer names. Look at all the win32 structures. Your average field name is about 20-30 chars there...

Does "size" include the signature and the "size" field itself?

cci - Input color coding
0 - R'G'B'
> 0 - Y'Cb'Cr' - index to luma_matrix_coeffs
cco - Output color coding
0 - R'G'B'
> 0 - Y'Cb'Cr' - index to luma_matrix_coeffs
What does "luma_matrix_coeffs" mean? How about this?

COLOR_CODING_RGB = 0;
COLOR_CODING_YCbCr = 1;
COLOR_CODING_LUMA_MATRIX_COEFFS = 0x10000;

The matrix coeffs (whatever they mean) would then be "cci & 0xffff". And we'd have a lot of room for additional values between YCbCr and luma_matrix_coeffs for potential future use. But since I don't really know what is meant with matrix coeffs, my suggestion may very well be stupid. So take it with a pinch of salt, please...

pver - Version of the program that created the file
That should be a long int (64bit) to be win32 file version compatible.

Rest looks fine to me.

IMHO for video it would be like this:
-3D LUT 8bit and GC LUT 8bit: do all processing in 3D LUT
-3D LUT 8bit and GC LUT 10bit: do all processing in 3D LUT except gamma correction to fit displays gamma, this should be done in the GC LUT, which has higher accuracy
-3D LUT 16bit dithered to 8bit: do all processing in 3D LUT.
The last option is not available, and I don't know if it will ever be.
I think you're being too pessimistic... :)

This is part of my plans, but in fact the gamma correction would be part of the CMS, the last step.
That would be very nice!!

Floyd-Steinberg could be the best balance between quality and speed. From the dithering wiki-page (http://en.wikipedia.org/wiki/Dithering) the stucki method looks the best for me, but probably it would be too slow and/or too complicated to add...
I think the differences between the colors are small enough with RGB24 so that Stucki won't have much of an advantage over Floyd-Steinberg. Actually I think maybe using random dithering (like in audio processing) would even be superior to using either Stucki or Floyd-Steinberg. Random dithering looks bad if the color differences are big. But I think with small color differences random dithering could play out to be surprisingly good. Well, I'm only speculating, of course...

So it should be: "16 bit" better than "16bit dithered to 8bit" better than "8bit".
Fully agreed. However, "16bit dithered to 8bit" should be a lot nearer to 16bit than to 8bit. That is, if there's any difference visible between 16bit and 8bit at all. Jury is still out on that, I have to admit...

tritical
8th February 2009, 22:50
I can add 16 bit to 8 bit support, but it will take a little while. rgb3dlut really needs to be rewritten so that the yuy2 -> packed 4:4:4 upsampling step is separate from the packed 4:4:4 -> RGB conversion via lut step. Right now 14 separate code paths exist in rgb3dlut (12 for yuy2 input w/ rgb output), and I'd have to add 16->8 support to all of them. Separating the upsampling out would leave only 4 code paths. I'm skeptical if 16-bit output with dithering to 8-bit, given 8-bit input, will make any real difference though (we're talking about changing r/g/b values by +-1).

My current plans are:

separate rgb3dlut and yv12toyuy2 from ddcc
rename rgb3dlut to 3dlut
add rgb->yuy2, yuy2->yuy2, and yv12->yv12 support
separate upsampling/downsampling steps inside 3dlut (4:2:2->4:4:4,4:4:4->4:2:2) from lut step

After that, I will add 16-bit lut output w/ dithering to 8-bit. I can't say how fast all of this will happen. I do have other stuff that I actually get paid to work on :D.

The proposed header looks ok to me, but it doesn't make much difference to rgb3dlut anyways... aside from some error checking and automatic parameter setting. I think the specific values of cci/cco should be listed though.

madshi
9th February 2009, 09:23
@tritical, that sounds awesome - thanks! It will be very interesting to see whether dithering does or does not make a visible difference. I guess we'll need some fancy test screens for that then with very smooth color and brightness gradations...

@yesgrey3 & tcritical, here are some additional thoughts about bitdepth and array / file format:

input bitdepth

For unscaled progressive sources 8bit input should be good enough. But eventually if deinterlacing and scaling is made use of, having slightly higher input bitdepth may be worth a thought. But of course the needed memory size grows astronomical, unfortunately. But:

(1) Deinterlacing and scaling are usually done in YCbCr and not in RGB, AFAIK.
(2) Brightness information is more important than color information.
(3) For the array access we need to convert to YCbCr 4:4:4, so we put too much weight on color information compared to brightness information.

So my thought is this: Would it make sense to (optionally) up the Y bitdepth to 10bit while leaving Cb and Cr at 8bit? That would increase needed memory by factor 4x, which is a lot, but still manageable, I think. Of course this input format would make sense only if there was a deinterlacing/scaling algorithm which outputs more than 8bit. Don't know if any such thing exists yet. But even if it doesn't exist yet, who knows what the future will bring. FWIW, all the good hardware video processing chips calculate at least in 10bit YCbCr internally when doing deinterlacing & scaling etc...

One minor problem is that the current file format draft wouldn't support a funny input format like this. So I'd suggest splitting the "input/output bitdepth" field into 3 fields, one for each input/output component. E.g. "int inputBitdepth [3]".

array pack format

Thinking about memory sizes, and how to pack the output data:

We could split the array into 3 parts, one for each output component. This would give the program loading the 3dlut the chance to load the array into memory in 3 separate chunks. That is a big advantage, especially if the array sizes get rather big. E.g. Y10Cb8Cr8 input and R16G16B16 output would require an array of 384MB. Now the memory consumption itself is still manageable, but the bigger problem is the limited address range in a 32bit process. There's only 4GB of memory address range available per 32bit process and the whole range gets fragmented already during creation and initialization of the process. Furthermore some of those 4GB are reserved to the OS. So it will be hard to find a memory address where you can put a continuous block of 384MB into. In my experience you can have good or bad luck allocating such a big continuous memory block. There's a chance that it might fail - especially inside of a typical DirectShow media player, which has loads of DirectShow filter dlls loaded. Chances would be much much higher for allocating 3 separate memory blocks à 128MB. So that's a really good argument for splitting the array into 3 chunks, one for each output component.

yesgrey
11th February 2009, 01:09
'3DLUT' are only 5 chars. So maybe the definition should be "char sig[5]"?
I was counting with the '\0' character, but I will change to 5.
Does "size" include the signature and the "size" field itself?
Yes. size is the size of the header. signature and size are part of the header.
That is, if there's any difference visible between 16bit and 8bit at all. Jury is still out on that, I have to admit...
That's the big question... We are very happy playing with all this bits stuff, but in the end probably we will not notice any difference (I will for sure, because I will not admit that all this work was for nothing...:D)
My current plans are:

Thanks for the planning. I will adjust my planning to yours.
I guess we'll need some fancy test screens for that then with very smooth color and brightness gradations...
You could start creating some...;)
If you don't know how to put them in video just post the pics here and I will do it.
here are some additional thoughts about bitdepth...
Interesting thoughts, but I think that without seeing it we will never know...
IMHO all this >8bit processing is important, because it's the only way of preserving the full 8bit color depth of the source... If we perform all these computations using 8bit, in the end we will keep only 6 or 7 bits of the source color depth...:(
Would it make sense to (optionally) up the Y bitdepth to 10bit while leaving Cb and Cr at 8bit?
Why not? Since I've decided to play the chicken I will put one more egg...:D
We could split the array into 3 parts, one for each output component.
I think that would be a bad idea. I agree with the splitting, but not like that. When we access the 3D LUT, we always retrieve 3 values (r,g,b or y,cb,cr), so, these three values should be stored together. I think it would be better splitt the 3D LUT file for Cb values
For example, for YCbCr(10bit;8bit;8bit):
(Y:0-1023;Cb:0-255;Cr:0-63)+(Y:0-1023;Cb:0-255;Cr:64-127)+(Y:0-1023;Cb:0-255;Cr:128-191)+(Y:0-1023;Cb:0-255;Cr:192-255)

Let's see what tritical thinks about it...

yesgrey
11th February 2009, 01:27
Here is the second iteration for the definition of a file format for the 3D LUT (with names more like at Microsoft way...;)):
struct
{
char signature[5];
int headerSize, fileVersion;
int inputBitDepth[3], outputBitDepth[3];
int inputColorEncoding, outputColorEncoding;
char programName[20];
long int programVersion;
int parametersSize;
int reserved1, reserved2;
} h3dlut;

/* 3D LUT file specification:

// Header
signature - File signature; must be: '3DLUT'
headerSize - File header size in bytes
fileVersion - File format version number
inputBitDepth - Input bit depth per component (Y,Cb,Cr or G,B,R)
outputBitDepth - Output bit depth per component (Y,Cb,Cr or G,B,R)
inputColorEncoding - Input color encoding standard
- ...
outputColorEncoding - Output color encoding standard
- ...
programName - Name of the program that created the file
programVersion - Version of the program that created the file
parametersSize - Size in bytes of the array of char with a copy of the
run parameters settings used for creating the file
reserved1 - Reserved for future usage
reserved2 - Reserved for future usage

// Parameters Settings
parametersSize bytes
// Data
outputBitDepth=8:
offset = (cr<<(2*inputBitDepth[1])+cb<<(inputBitDepth[0])+y)*3 (YCbCr input)
offset = ( r<<(2*inputBitDepth[1])+ b<<(inputBitDepth[0])+g)*3 (RGB input)
size = 3*(2^inputBitDepth[0]*2^inputBitDepth[1]*2^inputBitDepth[2]) bytes
outputBitDepth<=16:
offset = (cr<<(2*inputBitDepth[1])+cb<<(inputBitDepth[0])+y)*6 (YCbCr input)
offset = ( r<<(2*inputBitDepth[1])+ b<<(inputBitDepth[0])+g)*6 (RGB input)
size = 3*(2^inputBitDepth[0]*2^inputBitDepth[1]*2^inputBitDepth[2])*2 bytes
(This is the general formula for the 3 3D LUT tables offset and size)
*/
I have not decided yet how to indicate the ColorEncoding values, I will update the specification later. I need a little more time to think about it.

I think that the offset navigation should be in bytes, so, when outputBitDepth > 8 it will assume always a 16bit output 3D LUT size. Maybe it's better only considering 8bit or 16bit output, or we will have to decide how to deal with the bits not used...

Comments/sugestions are welcome.

Mug Funky
11th February 2009, 07:10
you're gonna have to wait forever before display drivers actually support 10 bits.

http://h20331.www2.hp.com/hpsub/cache/596803-0-0-225-121.html

nvidia's higher end cards will do 10 (or 12) bit output via an SDI option (HDMI can carry it too, i believe).

also sony BVM monitors have been doing 10-bit for years (since 1992?). whether it achieves a noise floor below -48dB i'm not sure, but they certainly don't visibly band on gentle gradients.

madshi
11th February 2009, 09:43
You could start creating some...;)
If you don't know how to put them in video just post the pics here and I will do it.
The problem is that ideally a test screen should be created in YCbCr and not in RGB. E.g. a smooth gradiant from lowest to highest brightness in YCbCr in one bit steps would be helpful. And I don't know how to create YCbCr pics.

Why not? Since I've decided to play the chicken I will put one more egg...:D
Great - thanks!!

I think that would be a bad idea. I agree with the splitting, but not like that. When we access the 3D LUT, we always retrieve 3 values (r,g,b or y,cb,cr), so, these three values should be stored together.
I changed my mind. Please ignore my splitting suggestion. Because I think it is not the responsibility of a file format to dictate how the data has to be stored in RAM. I think it's the task of the software which loads the 3dlut data to store the data in RAM in the best possible way. If the array needs to be split in order to be mappable it into RAM, then let the software which loads the data do this work. I think you should just write one big continuous data array (just like you originally planned) and be done with it.

Here is the second iteration for the definition of a file format for the 3D LUT (with names more like at Microsoft way...;)):
struct
{
char signature[5];
int headerSize, fileVersion;
int inputBitDepth[3], outputBitDepth[3];
int inputColorEncoding, outputColorEncoding;
char programName[20];
long int programVersion;
int parametersSize;
int reserved1, reserved2;
} h3dlut;

/* 3D LUT file specification:

// Header
signature - File signature; must be: '3DLUT'
headerSize - File header size in bytes
fileVersion - File format version number
inputBitDepth - Input bit depth per component (Y,Cb,Cr or G,B,R)
outputBitDepth - Output bit depth per component (Y,Cb,Cr or G,B,R)
inputColorEncoding - Input color encoding standard
- ...
outputColorEncoding - Output color encoding standard
- ...
programName - Name of the program that created the file
programVersion - Version of the program that created the file
parametersSize - Size in bytes of the array of char with a copy of the
run parameters settings used for creating the file
reserved1 - Reserved for future usage
reserved2 - Reserved for future usage
Looks fine to me! Could you please add "char parameter data [?]" to the end of the "h3dlut" structure definition, just to make clear where the parameter data is stored?

// Parameters Settings
parametersSize bytes
// Data
outputBitDepth=8:
offset = (cr<<(2*inputBitDepth[1])+cb<<(inputBitDepth[0])+y)*3 (YCbCr input)
offset = ( r<<(2*inputBitDepth[1])+ b<<(inputBitDepth[0])+g)*3 (RGB input)
size = 3*(2^inputBitDepth[0]*2^inputBitDepth[1]*2^inputBitDepth[2]) bytes
outputBitDepth<=16:
offset = (cr<<(2*inputBitDepth[1])+cb<<(inputBitDepth[0])+y)*6 (YCbCr input)
offset = ( r<<(2*inputBitDepth[1])+ b<<(inputBitDepth[0])+g)*6 (RGB input)
size = 3*(2^inputBitDepth[0]*2^inputBitDepth[1]*2^inputBitDepth[2])*2 bytes
(This is the general formula for the 3 3D LUT tables offset and size)
*/
I think that the offset navigation should be in bytes, so, when outputBitDepth > 8 it will assume always a 16bit output 3D LUT size. Maybe it's better only considering 8bit or 16bit output, or we will have to decide how to deal with the bits not used...
Agreed, using only 8bit or 16bit byte packed output sounds just fine to me. If the software loading the file thinks its better to use bit packing, it can rearrange the array to its liking.

But, I think the offset calculation is wrong. Shouldn't it be this way?

offset = (cr << (inputBitDepth[1] + inputBitDepth[0]) + cb << (inputBitDepth[0]) + y) * 3 (YCbCr input)

leeperry
11th February 2009, 10:26
http://h20331.www2.hp.com/hpsub/cache/596803-0-0-225-121.html

nvidia's higher end cards will do 10 (or 12) bit output via an SDI option (HDMI can carry it too, i believe).

also sony BVM monitors have been doing 10-bit for years (since 1992?). whether it achieves a noise floor below -48dB i'm not sure, but they certainly don't visibly band on gentle gradients.
well, any video card can do 30bit on VGA, it's mostly 8 bit + 10bit LUT...I can use ARGYLLCMS to measure that the LUT is in 10bit.
we're stuck to RGB24 over HDMI/DVI coz the TMDS encoder works in RGB24 anyhow.
oh sure, there must be some high end cards that can do true 10bit on SDI/dual link DVI, but these are not consumer items AFAIK.
it would appear that the HDMI 1.3 licences would be so high that there's hardly any soundcard compatible, let alone graphic card.

honai
11th February 2009, 13:07
This might be a useful 1920x1080 pattern to detect banding/dithering issues:

http://web.comhem.se/zacabeb/repository/spectrum_rgb.png

madshi
11th February 2009, 15:03
I've just had an idea about how to make *any* input bitdepth work with a relatively small (e.g. 8bit input, 16bit output) 3dlut array:

Instead of rounding the input down to the native 3dlut bitdepth, we read the 8 nearest RGB output values from the 3dlut array. Then we average these 8 values down (weighted average) to interpolate the final RGB output value.

I'm thinking of the 3dlut array like a net of 3D cubes. Each value in the 3dlut array is one cube corner. Now if we have an input bitdepth higher than the native 3dlut array, the input usually doesn't fall directly on a 3dlut array cube corner. Instead it's somewhere in the middle of one of those cubes. So we read the surrounding cube corner values and interpolate the final output value, based on how far the input value is away from each of the 8 corners.

Does that make any sense to you? Of course my suggestion would result a noticeable performance loss, cause we'd have to read 8 array values instead of just one and we'd have to use some crazy formula to combine these 8 values into the final output value. But I think the result should be very near to perfect. It should *almost* be as good as having a 3dlut with a much higher native input bitdepth.

Thoughts?

Anyone willing to write a formula to calculate the final output value? Unfortunately my math sucks...

tritical
12th February 2009, 01:05
I would like to change the lookup into the rgb lut to be:

(r<<16)+(g<<8)+b

Also, I am dropping the idea of adding yv12->yv12 support as it just doesn't make sense (internally it would have to convert to 4:4:4 somehow, so might as well require yuy2 input and let the user decide how to do the yv12->yuy2 conversion).

@madshi
Your idea is basically the same idea that is used with smaller luts, such as 16x16x16, applied to higher bitdepths... for input values that don't fall on the samples defined by the lut interpolate inside the cube. I think that for input sources with greater than 8-bits this is the way to go due to memory requirements. So stick with an 8-bit input, 16-bit output and interpolate.

yesgrey
12th February 2009, 01:44
But, I think the offset calculation is wrong. Shouldn't it be this way?
offset = (cr << (inputBitDepth[1] + inputBitDepth[0]) + cb << (inputBitDepth[0]) + y) * 3 (YCbCr input)
Yes, you're right. I will correct it in iteration 3.:o
I would like to change the lookup into the rgb lut to be:
(r<<16)+(g<<8)+(b<<8)

Is this correct? or would it be: (r<<16)+(g<<8)+b
I have suggested: (r<<16)+(b<<8)+g
to keep the correlation Y->G; Cb->B; Cr->R.
as indicated in the ITU specifications, but for me it's ok to use it as you suggested... and what about the output format, do you also agree to always use 1 byte or 2byte?

tritical
12th February 2009, 02:04
Yep, I meant

(r<<16)+(g<<8)+b

and

(v<<16)+(u<<8)+y

So that lookups using rgb packed as: b,g,r in memory, and yuv packed as: y,u,v in memory form the lookup the same way in terms of reading/shifting from memory locations. I agree only 1 byte and 2 byte outputs.

madshi
12th February 2009, 09:43
Also, I am dropping the idea of adding yv12->yv12 support as it just doesn't make sense (internally it would have to convert to 4:4:4 somehow, so might as well require yuy2 input and let the user decide how to do the yv12->yuy2 conversion).
I'm wondering: As far as I understand yv12 is 4:2:0 and yuy2 is 4:2:2, right? Is there also an "official" fourcc for 4:4:4 YCbCr? And wouldn't it be faster and better to convert 4:2:0 directly to 4:4:4 instead of doing 4:2:0 -> 4:2:2 -> 4:4:4?

Your idea is basically the same idea that is used with smaller luts, such as 16x16x16, applied to higher bitdepths... for input values that don't fall on the samples defined by the lut interpolate inside the cube. I think that for input sources with greater than 8-bits this is the way to go due to memory requirements.
And there I thought I had a brand new idea... :o

Anyway, is there code available anywhere (or at least a formula) on how to "interpolate inside the cube"?

Thanks!

yesgrey
12th February 2009, 12:22
Is there also an "official" fourcc for 4:4:4 YCbCr?
YV24.
And wouldn't it be faster and better to convert 4:2:0 directly to 4:4:4 instead of doing 4:2:0 -> 4:2:2 -> 4:4:4?

This was discussed a few posts back. That was the reason for tritical create the yv12toyuy2 filter, so we could test if we could notice any quality difference, since ffdshow is performing yv12->yv24 with no intermediate yuy2 step.;)
My first tests showed that yv12->yv24 was slightly better, but I haven't tested yet the more recent versions of rgb3dlut and yv12toyuy2 with the new options for the chroma sampling position...
In the end, maybe the difference is only noticeable in still zoomed pictures, and nobody see a movie that way...:D

yesgrey
12th February 2009, 14:20
Here is the third iteration for the definition of a file format for the 3D LUT:
// 3D LUT file specification (fileVersion=1):
struct
{
char signature[5];
int headerSize, fileVersion;
int inputBitDepth[3], outputBitDepth[3];
int inputColorEncoding, outputColorEncoding;
char programName[20];
long int programVersion;
int parametersSize;
int reserved1, reserved2;
} h3dlut;
char parametersData[];
void lut3d[];
/*
// Header
signature - File signature; must be: '3DLUT'
headerSize - File header size in bytes
fileVersion - File format version number
inputBitDepth - Input bit depth per component (Y,Cb,Cr or G,B,R)
outputBitDepth - Output bit depth per component (Y,Cb,Cr or G,B,R)
inputColorEncoding - Input color encoding standard
- ...
outputColorEncoding - Output color encoding standard
- ...
programName - Name of the program that created the file
programVersion - Version of the program that created the file
parametersSize - Size in bytes of the array of char with a copy of the
run parameters settings used for creating the file
reserved1 - Reserved for future usage
reserved2 - Reserved for future usage

// Parameters Settings
parametersData - pointer to an array of char with size parametersSize
// 3D LUT Data
lut3d - pointer to an array that contains the 3dlut output values.
The type of the lut3d array entries is defined by the outputBitDepth values:
-If all outputBitDepth values are 8, it's an array of unsigned char.
-If any of outputBitDepth values is >8 and <=16, it's an array of unsigned short.
The offset and dimension of the array are calculated as:
offset = (cr<<(inputBitDepth[1]+inputBitDepth[0])+cb<<(inputBitDepth[0])+y)*3 (YCbCr input)
offset = ( r<<(inputBitDepth[1]+inputBitDepth[0])+ g<<(inputBitDepth[0])+b)*3 (RGB input)
dimension = 3*(2^inputBitDepth[0]*2^inputBitDepth[1]*2^inputBitDepth[2])
(This is the general formula for the 3 3D LUT tables offset and size)
*/

I have not decided yet how to indicate the ColorEncoding values, I will update the specification later. I need a little more time to think about it.

We could simplify it a little by using outputBitDepth as the same for all output channels, but the way it is now is more future proof...

Comments/sugestions are welcome.

If you all agree with this I will start working in cr3dlut v2.0 to release the first "official" version of the 3DLUT file format.

madshi
12th February 2009, 15:13
YV24.
Ah, never heard of that one yet! I wonder why ffdshow doesn't allow YV24 output?

Here is the third iteration for the definition of a file format for the 3D LUT
Looks good to me. Two minor cosmetic things:

(1) "char parametersData[];" should be the last element of the h3dlut struct definition, so it should be inside the structure, not outside. At least that's how win32 structures like that are usually done.

(2) offset and dimension can be either "3*" or "6*", depending on output bitdepth.

Thanks!

honai
12th February 2009, 17:26
I wonder why ffdshow doesn't allow YV24 output?


Probably because no DirectShow video renderer exists for YV24 on the Windows platform.

yesgrey
12th February 2009, 21:08
(1) "char parametersData[];" should be the last element of the h3dlut struct definition
I have think on that, but did not want to add the pointer to the header, because it would be completelly useless to store it. But you're right, more 4 bytes will make no harm.
(2) offset and dimension can be either "3*" or "6*", depending on output bitdepth.
No. The offset and dimension are always the same, what changes is the entries type. 'char' for 8bit output, and 'short' for 16 bit output.

madshi
12th February 2009, 21:16
I have think on that, but did not want to add the pointer to the header, because it would be completelly useless to store it. But you're right, more 4 bytes will make no harm.
I thought the first character was stored right after "reserved2" without any pointers?

yesgrey
12th February 2009, 21:16
Here is the fourth iteration for the definition of a file format for the 3D LUT:
// 3D LUT file specification (fileVersion=1):
struct
{
char signature[5];
int headerSize, fileVersion;
int inputBitDepth[3], outputBitDepth[3];
int inputColorEncoding, outputColorEncoding;
char programName[20];
long int programVersion;
int parametersSize;
int reserved1, reserved2;
char parametersData[];
} h3dlut;
void *o3dlut;
/*
// Header
signature - File signature; must be: '3DLUT'
headerSize - File header size in bytes
fileVersion - File format version number
inputBitDepth - Input bit depth per component (Y,Cb,Cr or R,G,B)
outputBitDepth - Output bit depth per component (Y,Cb,Cr or R,G,B)
inputColorEncoding - Input color encoding standard
- ...
outputColorEncoding - Output color encoding standard
- ...
programName - Name of the program that created the file
programVersion - Version of the program that created the file
parametersSize - Size in bytes of the array of char with a copy of the
run parameters settings used for creating the file
reserved1 - Reserved for future usage
reserved2 - Reserved for future usage
parametersData - pointer to an array of char with size parametersSize
// Output data
o3dlut - pointer to an array that contains the 3dlut output values.
The type of the o3dlut array entries is defined by the outputBitDepth values:
-If all outputBitDepth values are 8, it's an array of unsigned char.
-If any of outputBitDepth values is >8 and <=16, it's an array of unsigned short.
The offset and dimension of the array are calculated as:
offset = (cr<<(inputBitDepth[1]+inputBitDepth[0])+cb<<(inputBitDepth[0])+y)*3 (YCbCr input)
offset = ( r<<(inputBitDepth[1]+inputBitDepth[0])+ g<<(inputBitDepth[0])+b)*3 (RGB input)
dimension = 3*(2^inputBitDepth[0]*2^inputBitDepth[1]*2^inputBitDepth[2])
(This are the general formulas for the 3D LUT offset and dimension
assuming: char = 1 byte; short = 2 byte; int = 4 byte; long int = 8 byte)
*/

I have not decided yet how to indicate the ColorEncoding values, I will update the specification later. I need a little more time to think about it.

@tritical,
We could define it later, but how should we store <16bit values in the 'short'? MSB or LSB?

Comments/sugestions are welcome.