Log in

View Full Version : madVR - high quality video renderer (GPU assisted)


Pages : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 [465] 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329

cyberbeing
15th February 2014, 19:07
I do think that in an ideal world madVR would contain an option to specify that your display is callibrated to an sRGB gamma curve and error dithering would use this setting to convert values to linear light. But given that most people haven't callibrated their displays or even know which gamma curve is closest to their display's, this may be overly complicated and not particularly useful.

madVR actually had a functionality like this in the past (0.61 and prior?) which was available when using a 3DLUT, but it has long since been simplified to assume a source gamma of 2.2 for all linear light processing.

mahoushounen
15th February 2014, 19:15
After upgrading madVR to 0.87.4 and MPC-HC to 1.7.3, it stopped taking screenshots with subtitles. Should it be this way, or did I accidentally break something?

Shiandow
15th February 2014, 19:22
madVR actually had a functionality like this in the past (0.61 and prior?) which was available when using a 3DLUT, but it has long since been simplified to assume a source gamma of 2.2 for all linear light processing.

Well, in most situations you wouldn't even notice the small differences between the gamma curves. Unfortunately the difference between sRGB linear light and pure power gamma is pretty large for values near black, which seems to be the region where minor mistakes in error-diffusion become most noticeable.

Ver Greeneyes
15th February 2014, 19:23
float3 calcPixelLinear(float3 gammaPixel, float3 collectedError, float randomValue, out float3 newError)
{
float3 tempPixel = gammaPixel * 255.0f;
float3 floorG = floor(tempPixel) / 255.0f;
float3 ceilG = ceil (tempPixel) / 255.0f;
float3 floorL = convertToLinear(floorG);
float3 ceilL = convertToLinear( ceilG);
bool3 useFloor = convertToLinear(gammaPixel + randomValue) + collectedError < 0.5 * (floorL + ceilL);
newError = clamp(convertToLinear(gammaPixel) + collectedError, floorL, ceilL) - ((useFloor) ? floorL : ceilL);
return (useFloor) ? floorG : ceilG;
}
Hmm, so looking through this ... collectedError and newError are in linear light, whereas gammaPixel and randomValue are in gamma light. You then calculate if the result should be floorL or ceilL in linear light, and use floorG and ceilG accordingly back in gamma light. randomValue being in gamma light seems correct; that way its effect isn't magnified near black.

So then to update the linear light collected error, you would take its current value and add to it the difference between the ideal value convertToLinear(gammaPixel) and the actual result, (useFloor) ? floorL : ceilL. Which is what you do, aside from the clamp call. The clamp call then ensures that the new value will be between -(ceilL - floorL) and (ceilL - floorL). I'm not sure how to reason about that one :) Is collectedError the accumulated error for the current pixel (from dithering itself and being influenced by surrounding pixels), or is it the remaining error of the color we're trying to dither?

Either way I agree with the others that convertToLinear isn't correct. You should either use the original Rec.709 transfer function, or use its effective gamma, which is 1.950477 or 1.924805 depending on whether you fit the forward or inverse transform. For transforming to linear light, 1.950477 gives the best fit. Following the specification (single precision, avoiding division) would givegammaValue = saturate(gammaValue);
return (gammaValue < 0.081 ? 0.2222222 * gammaValue : pow(0.9099181 * (gammaValue + 0.099), 2.222222));
I also made a version (to satisfy my OCD) that doesn't have the nasty discontinuity in it - this isn't to spec, but it's a pretty minor adjustment:
gammaValue = saturate(gammaValue);
return (gammaValue < 0.081 ? 0.2215435 * gammaValue : pow(0.9099181 * (gammaValue + 0.099), 2.222222));

Edit: Ah, I see discussion has moved on somewhat since I started writing this post. If you think Rec.709 isn't a good fit for monitors, then I still think sRGB might do better than a pure power law. I'll post some constants for that after I've had dinner.

kasper93
15th February 2014, 19:23
After upgrading madVR to 0.87.4 and MPC-HC to 1.7.3, it stopped taking screenshots with subtitles. Should it be this way, or did I accidentally break something?

1. It has nothing to do with madVR
2. Subtitles rendered by MPC-HCs ISR were never included in snapshots. You were probably using VSFilter like renderer, and now you don't. If you really need this "feature" install xy-vsfilter, but I would recomend you to stick with ISR or XySubFilter, but those doesn't include subs on snapshots.

madshi
15th February 2014, 19:33
As far as I know that transfer function is the on that is used for sRGB, in theory this should correspond to the brightness that is used by the monitor. Unless the monitor is using a pure gamma curve but I thought that most would use the sRGB standard. Unfortunately it seems unlikely that you can do this in a way that looks right for all screens, and the brightened examples don't really help since the brightening step itself needs to make assumptions about the way the screen displays the values.

I fear that you'd need more than 1 version too make it look right for all screens, ideally this should depend on the calibration settings for your screen in madVR.
For absolute perfection maybe it would be necessary to use the gamma curve the display is calibrated to. Or maybe not. I'm not totally sure. In any case, the key thing is: Even if I may not hit the correct gamma curve exactly, it should still be an improvement over using gamma light. Well, in theory. In practice, it seems most users don't like the look of linear light error diffusion... :(

I'm still not entirely sure why this 'clamp' is needed to avoid artifacts
It took me quite some time to understand it, myself. I think the key reason is the following:

If you limit the possible dither output to floor/ceil of the gammaValue, then consider the max linear light error values for the following gray levels:

0.5 * ((201 / 255) ^ 2.2 - (200 / 255) ^ 2.2) * 255 = 0.8243
0.5 * ((1 / 255) ^ 2.2 - (0 / 255) ^ 2.2) * 255 = 0.00065

This basically means that when doing error diffusion on a pixel with the value of ~200, the error of one pixel could go up to 0.8243. Imagine you have a single 200 pixel sitting in a black area. The max error of the single 200 pixel is spread to the black pixels. But the difference between pixels 1 and 0 is so much smaller in linear light. So it will take over 1000 pixels to get rid of the 0.8243 error. Do you see the problem?

I fear in linear light we probably have to get rid of the limiter. That way the error of 0.8243 will turn 2-3 neighbor black pixels much brighter, but after that the error will be fully spread.

Then I guess my understanding of linear gamma is reversed? The point isn't to change the display gamma of the source from 2.2 gamma to 1.0 linear gamma, but rather to remove the inverse transfer function so the source values will be linear on a 1.0 linear gamma device?
I'm always getting confused when using terms like "display gamma" and "gamma device" etc. So I don't really know what to reply.

My question is if your R'G'B' to RGB to R'G'B' operation was the same for both. In both cases you apply the conversion to linear light on textures(?), perform processing, then convert back to gamma corrected light? Or is something different? Essentially, could this problem with near-black tones we are seeing with the linear light error-diffusion, also be detrimental to the linear light scaling performed in madVR?
The same algorithm is used in many places in the madVR processing pipeline. I don't remember if there's any place where I use a different gamma curve. Maybe there is. Would have to dig through the source code to know for sure. One place where different gamma curves are used is of course if you enable gamma processing, or if you tell madVR that your display is already calibrated to a specific gamma curve.

Well, in most situations you wouldn't even notice the small differences between the gamma curves. Unfortunately the difference between sRGB linear light and pure power gamma is pretty large for values near black, which seems to be the region where minor mistakes in error-diffusion become most noticeable.
There's also the problem that when blurring images or downscaling images, if you don't do the blurring or downscaling in linear light, you'll get incorrect results. So scientific analyzation of all this must be done very carefully.

The clamp call then ensures that the new value will be between -(ceilL - floorL) and (ceilL - floorL). I'm not sure how to reason about that one :)
So above.

Is collectedError the accumulated error for the current pixel (from dithering itself and being influenced by surrounding pixels)
Yes, collectedError is the errors summed up by previously processed pixels.

Edit: Ah, I see discussion has moved on somewhat since I started writing this post. If you think Rec.709 isn't a good fit for monitors, then I still think sRGB might do better than a pure power law. I'll post some constants for that after I've had dinner.
Isn't sRGB the same as Rec.709? In any case, I believe using a pure power curve is the right way to go here.

cyberbeing
15th February 2014, 19:51
After upgrading madVR to 0.87.4 and MPC-HC to 1.7.3, it stopped taking screenshots with subtitles. Should it be this way, or did I accidentally break something?

If this is normal or not depends on the subtitle renderer you use.

With VSFilter.dll, you should always have subtitles in your screenshots.

With XySubFilter.dll, you will only have subtitles in your screenshots if you have the subtitle 'trade quality for performance' option enabled, and the video has not been resized. Alternatively, you can enabled 'Render to Orignal Video' and still have subtitles in screenshots after resizing as well, but you'll lose much of the benefit of using XySubFilter by doing so.

With the MPC ISR (Playback -> auto-load subtitles enabled), you will never have subtitles in screenshots.

I'm always getting confused when using terms like "display gamma" and "gamma device" etc. So I don't really know what to reply.

Yeah, I seem to remember that the last time we had that gamma processing debate long ago. In any case, if that shader code is the correct way of converting to linear light (using 1/0.45), the video would essentially look "normal" if you calibrated your monitor to a linear gamma of 1.0. If you instead viewed this video which you converted to linear light on a 2.2 calibrated monitor, it would appear as if you had set madVR's 'gamma processing' to a 4.88 power-curve.

Shiandow
15th February 2014, 19:52
This basically means that when doing error diffusion on a pixel with the value of ~200, the error of one pixel could go up to 0.8243. Imagine you have a single 200 pixel sitting in a black area. The max error of the single 200 pixel is spread to the black pixels. But the difference between pixels 1 and 0 is so much smaller in linear light. So it will take over 1000 pixels to get rid of the 0.8243 error. Do you see the problem?


I understand now why that would be a problem. With my test I tended to us perfect noiseless gradients so that would explain why I didn't encounter problems like that.


There's also the problem that when blurring images or downscaling images, if you don't do the blurring or downscaling in linear light, you'll get incorrect results. So scientific analyzation of all this must be done very carefully.


I think that for downscaling and blurring you might be able to get away with it if the gamma curve you're using is 'close enough'. The problem with error diffusion is that the different gamma curves cause dramatically different behaviour for values near black which is precisely the region where this is most noticeable...

Also it seems to be preferable to use a gamma curve which is right for very dark colours but completely wrong for lighter colours than the other way around. This has the strange consequence that no gamma correction is better than pure power gamma correction.

madshi
15th February 2014, 19:58
Here are 2 new builds, using 2.0 instead of 2.222:

http://madshi.net/madVRlinear20.rar

One build is using the limiter. The other build isn't. Without the limiter it's looking rather wild, I think. I'm currently thinking maybe we should trash the linear light error diffusion idea and stay with NL6?

For those interested, without the "clamp()" call in the limiter the artifact I mentioned looks like this:

http://madshi.net/clampErr.png

So basically the error caused by the brighter "17" pixels is so big (in linear light) that it's actually bigger than the pixel values of the dark gray background, so it takes an eternity for the error to be resolved. As a result the rest of the 16x16 error diffusion blocks sticks to either the floor or ceil of the gammaValue, depending on whether the error caused by the "17" pixels is positive or negative.

In any case, if that shader code is the correct way of converting to linear light (using 1/0.45), the video would essentially look "normal" if you calibrated your monitor to a linear gamma of 1.0. If you instead viewed this video which you converted to linear light on a 2.2 calibrated monitor, it would appear as if you had set madVR's 'gamma processing' to a 4.88 power-curve.
No. madVR's error diffusion is not converting the image to linear light. The image stays in gamma light (remember, the output is either floor(gammaValue) or ceil(gammaValue)). Only the error diffusion weight distributions and decisions are performed in linear light.

madshi
15th February 2014, 20:10
Also it seems to be preferable to use a gamma curve which is right for very dark colours but completely wrong for lighter colours than the other way around. This has the strange consequence that no gamma correction is better than pure power gamma correction.
Well, "without gamma correction" practically means doing gamma correction with a gamma value of 1.0, which will be incorrect for most displays. So maybe it would be a good idea to use linear light, but to aim intentionally low with the gamma value, e.g. using a gamma value of 1.5 or so? That should be better than 1.0 for all displays, no?

Shiandow
15th February 2014, 20:12
Well, "without gamma correction" practically means doing gamma correction with a gamma value of 1.0, which will be incorrect for most displays. So maybe it would be a good idea to use linear light, but to aim intentionally low with the gamma value, e.g. using a gamma value of 1.5 or so? That should be better than 1.0 for all displays, no?

Honestly if it is at all possible I'd try to use the sRGB transfer function. This should give a correct gamma for higher values and use gamma 1.0 for lower values.

XMonarchY
15th February 2014, 20:17
I noticed with the little-noise version (or all versions?) is that sometimes I notice quickly-moving dithering in some areas of the screen. Most of the time its fine but some scenes have places where its like 10000 tiny ants/dots moving around and its visible. Is this normal? I don't remember it like that with normal random dithering, but I may be wrong...

I integrated 1D LUT into 3D LUT and banding is gone completely! Everything is smooth!

Does it matter if I used CUVID acceleration in LAV Video for decoding?

I am a bit behind on a lot of stuff, so please forgive for sounding stupid... When you guys are talking about gamma adjustments - are you saying that using linear light will actually change the video gamma used or the dithering gamma? I am hoping that using 3D LUT and ED results in video rendering with exactly the type of gamma that 3D LUT specifies. For example, my current 3D LUT uses BT.1886 gamma. The resulting video should be displayed using that exact gamma curve. Why would you want to change that? You can't possible know what gamma gamma is used on a monitor/TV, so what is the point in changing it? It should be 1.0 linear AFAIK...

iSunrise
15th February 2014, 20:21
One thing I noticed with the little-noise version (or all versions?) is that sometimes I notice quickly-moving dithering in some areas of the screen. Most of the time its fine but some scenes have places where its like 10000 tiny ants/dots moving around and its visible. Is this normal? I don't remember it like that with normal random dithering, but I may be wrong...
The noisefloor is so low now with e.x. NL6 that you can see all kinds of noise appearing from the source itself. This doesnīt have to be a problem with the dithering itself and I also didnīt see any negative side-effects like that. Would be helpful if you could provide a sample or a screenshot of the scene where you think you see something unusual like that. But Iīm petty sure itīs the source.

Honestly if it is at all possible I'd try to use the sRGB transfer function. This should give a correct gamma for higher values and use gamma 1.0 for lower values.
Yes, at least thatīs what happens on my display, where sRGB is the only mode where I can easily differentiate lower values, while I still get every benefit of the higher ones when Iīm on 0-255.

bacondither
15th February 2014, 20:30
I would like to see a build with with the reverse bt709 gamma curve and see how it looks.

James Freeman
15th February 2014, 20:32
I'm currently thinking maybe we should trash the linear light error diffusion idea and stay with NL6?


Agreed.

Shiandow
15th February 2014, 20:41
I would like to see a build with with the reverse bt709 gamma curve and see how it looks.
Linearization gamma should use the inverse input formats gamma curve not the display.

I'm not sure if I understand you correctly but that seems to be wrong. The gamma curve is defined to be the function that transforms gamma light to linear light.

wolfman2791
15th February 2014, 20:59
Here are 2 new builds, using 2.0 instead of 2.222:

http://madshi.net/madVRlinear20.rar

One build is using the limiter. The other build isn't. Without the limiter it's looking rather wild, I think. I'm currently thinking maybe we should trash the linear light error diffusion idea and stay with NL6? Honestly, the build with the limiter looks quite good. Better than NL6 just looking at it with the naked eye. Maybe it's just me... but i thought i'd throw my 2 cents in there.

bacondither
15th February 2014, 21:00
I'm not sure if I understand you correctly but that seems to be wrong. The gamma curve is defined to be the function that transforms gamma light to linear light.

Yes! Sorry for being unclear.

This is taken from: http://www.poynton.com/notes/colour_and_gamma/GammaFAQ.html

9. What is gamma correction?

The Rec. 709 transfer function takes linear-light tristimulus value (here L) to a nonlinear component (here E'), for example, voltage in a video system:
http://www.poynton.com/notes/colour_and_gamma/Rec709_tristim.gif

The linear segment near black minimizes the effect of sensor noise in practical cameras and scanners. Here is a graph of the Rec. 709 transfer function, for a signal range from zero to unity:

http://www.poynton.com/notes/colour_and_gamma/transfer709.gif

An idealized monitor inverts the transform:

http://www.poynton.com/notes/colour_and_gamma/R-nonlin-709-2-seg.gif

Real monitors are not as exact as this equation suggests, and have no linear segment, but the precise definition is necessary for accurate intermediate processing in the linear-light domain. In a color system, an identical transfer function is applied to each of the three tristimulus (linear-light) RGB components.

kstuart
15th February 2014, 21:05
Final HD6450 settings with madVR 0.87.4 (for future readers):

Chroma upsampling - Bicubic 75 AR
Luma upsampling:
SD - Softcubic 80
greater than 30 fps - Bilinear
HD and less than 31fps - Lanzcos3 AR

Fullscreen Exclusive Mode
Aero On
Both separate devices
Maximum queue sizes (lots of memory)
8 backbuffers
16 frames in advance
delay playback start
Debanding On with default settings

Smooth Motion Off (uses too much GPU, and FSE/Aero solves same problems in my setup)
Random Dithering instead of Error Diffusion (ED uses too much GPU)
Automatic Deinterlacing Off (uses too much GPU, and my HDTV does a relatively good job for the few interlaced videos I watch)
don't analyze
don't rerender
1080p23, 1080p24, 1080p59, 1080p60, 1080i59, 1080i60 (just as a reference point of what my monitor allows)

NNED not even close to usable - went from 15ms to 250ms :)

Software Decoding (to leave GPU to do the above)

Thanks to madshi for creating this software and making it freely available!

And thanks to everyone whose posts contributed information used for the above, especially 6233638.

Looking forward to future enhancements...

Ver Greeneyes
15th February 2014, 21:13
I'm always getting confused when using terms like "display gamma" and "gamma device" etc. So I don't really know what to reply.Going from XYZ tristimulus values to sRGB or Rec.709 is usually called a 'forward transform' and applies a transfer function with an effective gamma of less than 1.0, to compensate the gamma of the display (e.g. 2.2).

Going from sRGB or Rec.709 to XYZ tristimulus values first linearizes the encoded RGB values by applying a transfer function with an effective gamma of more than 1.0. So yeah, in converting to linear light you need the values from the reverse transformation (though you don't use the associated matrix).

Isn't sRGB the same as Rec.709?No, sRGB uses the following transfer function (again in shader-friendly form):return (gammaValue < 0.04045 ? 0.07739938 * gammaValue : pow(0.9478673 * (gammaValue + 0.055), 2.4));This has a best fit effective gamma of 2.233337. With the discontinuity fixed, the above becomes:return (gammaValue < 0.03928571 ? 0.07738015 * gammaValue : pow(0.9478673 * (gammaValue + 0.055), 2.4));

In any case, I believe using a pure power curve is the right way to go here.I don't really know to be honest. However, note that those of us using 3DLUTs generally use Rec.709 as the source profile, so the Rec.709 transfer function should be the best match there. Then again, I guess that depends on when the 3DLUT is applied? If dithering is the last step, it's working on the native gamma of the monitor (or whatever 1DLUT is loaded into the GPU), so maybe it's not so clear cut. I guess you could invert the neutral axis of the 3DLUT and apply that, then apply the Rec.709 transfer function to get linear light.. but that would be a bit insane :D

By the way, I did use the Rec.709 transfer function when encoding my perceptually spaced test patterns. I could try it with a pure power function too.

Edit: I need to write these posts faster - already another page and a new build! ;)

Shiandow
15th February 2014, 21:18
Yes! Sorry for being unclear.

This is taken from: http://www.poynton.com/notes/colour_and_gamma/GammaFAQ.html

9. What is gamma correction?

The Rec. 709 transfer function takes linear-light tristimulus value (here L) to a nonlinear component (here E'), for example, voltage in a video system:

[...]

The linear segment near black minimizes the effect of sensor noise in practical cameras and scanners. Here is a graph of the Rec. 709 transfer function, for a signal range from zero to unity:

[...]

An idealized monitor inverts the transform:

[...]

Real monitors are not as exact as this equation suggests, and have no linear segment, but the precise definition is necessary for accurate intermediate processing in the linear-light domain. In a color system, an identical transfer function is applied to each of the three tristimulus (linear-light) RGB components.

I agree with that but I'm somewhat confused which of those functions you call the 'reverse gamma curve'. As far as I can tell the function we need to use is the second one:

http://www.poynton.com/notes/colour_and_gamma/R-nonlin-709-2-seg.gif

Ver Greeneyes
15th February 2014, 21:27
I agree with that but I'm somewhat confused which of those functions you call the 'reverse gamma curve'. As far as I can tell the function we need to use is the second one:

http://www.poynton.com/notes/colour_and_gamma/R-nonlin-709-2-seg.gifNo: the display has a gamma of 2.2, so the material encoded for it has a gamma of 1/2.2. To linearize that (i.e. get what the display will output), you have to then apply a gamma of 2.2 to it again.

Shiandow
15th February 2014, 21:34
No: the display has a gamma of 2.2, so the material encoded for it has a gamma of 1/2.2. To linearize that (i.e. get what the display will output), you have to then apply a gamma of 2.2 to it again.

According to your own post that function has a (mean) gamma of 1.950477. I agree that it isn't quite 2.2 but it is quite close.

6233638
15th February 2014, 21:34
Without the limiter it's looking rather wild, I think.It's certainly noisier, but it is doing much better on gradients than the build with the limiter in place.

This has been brightened significantly, but if you go across the room from your display, you should easily be able to see how much better the build without the limiter is.

http://abload.de/thumb/limunlimlvjhc.gif (http://abload.de/img/limunlimlvjhc.gif)

With the limiter in place, there are clear boundaries between each segment on a gradient.
Without it, it blends lighter and darker pixels together at that point.

I still dislike what NL6 does near black though, creating an obvious pattern. (lines)
http://abload.de/thumb/linesluk7t.png (http://abload.de/img/linesluk7t.png)


Sorry, I know I keep going back on what I've said in the past about the dither algorithms, but I really think cyberbeing is right now, and the higher noise algorithms (more random/better blending) actually produce better results than the "low noise" ones.

Ver Greeneyes
15th February 2014, 21:38
According to your own post that function has a (mean) gamma of 1.950477. I agree that it isn't quite 2.2 but it is quite close.Oops! I misread your post.

GCRaistlin
15th February 2014, 21:40
MPC-HC hangs on with madVR as a renderer and ffdshow raw video external filter enabled:
http://rusfolder.com/39636769 (20 MB sample).
Just move the mouse cursor over menu buttons.

WinXP SP3
ffdshow_rev4530_20140209_clsid.exe
madVR 0.87.4
MPC-HC.1.7.3.23.x86.7z

I'm not sure who's guilty of that so I've reported the issue to MPC-HC developers and to ffdshow developers.

Shiandow
15th February 2014, 21:41
Oops! I misread your post.

I thought you might, since you suggested essentially the same function just a few posts ago. For the record I think that the sRGB variants you posted will give a better result, but I was trying to figure out which function bacondither meant by 'reverse gamma curve'.

madshi
15th February 2014, 21:42
So I've created a build with BT.709 transfer function, and it looks almost 100% identical to the original gamma light NL6. The inside of the gray bars are a pixel-by-pixel match, only the borders of the gray bars differ slightly.

Shiandow
15th February 2014, 21:48
So I've created a build with BT.709 transfer function, and it looks almost 100% identical to the original gamma light NL6. The inside of the gray bars are a pixel-by-pixel match, only the borders of the gray bars differ slightly.

Well, you'd expect it to be identical for RGB values below 20, it is the higher values where they differ.

leeperry
15th February 2014, 22:36
I'm currently thinking maybe we should trash the linear light error diffusion idea and stay with NL6?
It's 10PM here so definitely not the best time for this kind of comparison game but I still see a major lack of clarity and transparency in the two new LL builds compared to NL6 GL(that looks most outstanding here on real-world movies from a +1m distance).

I'll recompare them again tomorrow morning.

GREG1292
15th February 2014, 22:54
LL build with display recalibrated looks fine on my end.
Chroma upscaling 32needi 3
32/16 doubling always
Lancos 8 all checked
Jinc 4 all checked
All looks good and clear on 1080p 48% gpu
720p 78% gpu
On a gtx770 no dropped frames or stuttering the build looks great to
Me. Seems like the LL is more Efficient. Can run 64 neurons on 1080p.
I'm just reporting what my eyes see and cannot get NL6 to look better on
my projector. Will test the new builds tomorrow.


Sent from my iPhone using Tapatalk

NicolasRobidoux
15th February 2014, 23:01
...
I would like to see what your modified Jinc5 can do. This test image might be a good candidate for pixel art:

http://madshi.net/SNES.png

Here are comparisons between NNEDI3 vs. Jinc3AR, and between Jinc3AR vs. Jinc3:

http://screenshotcomparison.com/comparison/59698
http://screenshotcomparison.com/comparison/59702

I'm not done digging through what I've done (at this point I think that for for pixel art one of the deblurred Jinc4 is best in the antialiasing department when combined with an effective anti-ringing system, which in my case was sigmoidization), but I must say that I like the "maximally sharpened Jinc3" performed through linear light.

The important caveat is this: It's clear that the choice of intermediate color space has a high impact, and that this choice is highly dependent on the colorspace of the source material. So, I'm not sure that enlarging through linear light will work well with video, be it pixel art video.

Here is a link to the result ofconvert SNES.png -colorspace RGB -define filter:blur=0.88549061701764 -filter Lanczos -distort Resize 1234x -colorspace sRGB SNES.lanczosSharpest3.throughRGB.png
http://web.cs.laurentian.ca/nrobidoux/misc/SNES.lanczosSharpest3.throughRGB.png

This "maximally sharpened Jinc3" was eventually nicknamed EWA LanczosSharpest 3-lobe and its mathematical derivation is discussed here: http://www.imagemagick.org/discourse-server/viewtopic.php?f=22&t=19636&start=30#p78347

madshi
15th February 2014, 23:09
I'm not done digging through what I've done (at this point I think that for for pixel art one of the deblurred Jinc4 is best in the antialiasing department when combined with an effective anti-ringing system, which in my case was sigmoidization), but I must say that I like the "maximally sharpened Jinc3" performed through linear light.

The important caveat is this: It's clear that the choice of intermediate color space has a high impact, and that this choice is highly dependent on the colorspace of the source material. So, I'm not sure that enlarging through linear light will work well with video, be it pixel art video.

Here is a link to the result ofconvert SNES.png -colorspace RGB -define filter:blur=0.88826421508540347 -filter Lanczos -distort Resize 1234x -colorspace sRGB lanczosSharpest3.throughRGB.png
http://web.cs.laurentian.ca/nrobidoux/misc/SNES.lanczosSharpest3.throughRGB.png
Hmmmm... I like madVR's Jinc3 AR better. And NNEDI3 is another class, IMHO.

http://screenshotcomparison.com/comparison/59698

------------

Ok, here's a gamma light error diffusion test build with an "adaptive" noise level. What do you guys think?

http://madshi.net/madVRedAdaptive.rar

6233638
15th February 2014, 23:21
Ok, here's a gamma light error diffusion test build with an "adaptive" noise level. What do you guys think?

http://madshi.net/madVRedAdaptive.rar
It seems better than the Gamma Light build (similar appearance, though slightly more random) but the limiter is still creating bands on gradients, as there are no areas where three shades are blended together.


Adaptive/Gamma Light (http://abload.de/img/gamma-adaptivekqbly.gif)
Adaptive/Unlimited (http://abload.de/img/adaptive-unlimitedirzhn.gif)

bacondither
15th February 2014, 23:29
It seems better than the Gamma Light build (similar appearance) but the limiter is still creating bands on gradients, as there are no areas where three shades are blended together.

I get dither dots on everything that should be black on the build without the limiter.

madVR - linear 2.0 unlimited (http://i.imgur.com/2hE69Fz.png)

And yes, the adaptive build looks better.. time to sleep...

madshi
16th February 2014, 00:24
It seems better than the Gamma Light build (similar appearance, though slightly more random) but the limiter is still creating bands on gradients, as there are no areas where three shades are blended together.


Adaptive/Gamma Light (http://abload.de/img/gamma-adaptivekqbly.gif)
Adaptive/Unlimited (http://abload.de/img/adaptive-unlimitedirzhn.gif)

Three shades don't need to be blended together, they actually *should* not be blended together. From the view point of error diffusion two shades of dots are perfectly capable of reproducing any needed brightness value in between those two shades. In its purest form, error diffusion only has black and white in its palette and recreates a whole grayscale with that. So there isn't really any need to blend 3 shades together.

Looking at your screenshot I would say that the banding problem seems to be fully solved. If you look at each pixel column separately and practically blur the whole height of the column into one pixel, each column seems to have a different brightness value, and that's exactly how it's supposed to be. In the original NL6 build that is not the case. The NL6 build has multiple columns next to each other without any diffusion dots. The adaptive build doesn't seem to have this problem.

Of course you can cover the whole gradient with loads of additional noise (like the "unlimited" build does) to make it look smoother in those contrast boosted screenshots. But that's really a "cover up", IMHO. The contrast is boosted in those screenshots so much that it can't really look smooth. But if you allow the different shades to be 8bit steps, the result should be perfectly smooth without any visible banding.

The look should be slightly more random in some parts, but also slightly less random in other parts. In my own tests in some gradient sections the adaptive build looked less noisy compared to the original NL6 build. But I guess that depends on the exact test image.

Now I just hope that everybody (both "scientists" and "human observers" :)) will like the adaptive build!

cyberbeing
16th February 2014, 00:49
In any case, if that shader code is the correct way of converting to linear light (using 1/0.45), the video would essentially look "normal" if you calibrated your monitor to a linear gamma of 1.0. If you instead viewed this video which you converted to linear light on a 2.2 calibrated monitor, it would appear as if you had set madVR's 'gamma processing' to a 4.88 power-curve.No. madVR's error diffusion is not converting the image to linear light. The image stays in gamma light (remember, the output is either floor(gammaValue) or ceil(gammaValue)). Only the error diffusion weight distributions and decisions are performed in linear light.

I think you took my reply out of context, since I don't see how it can be answered with a "no". I was just clarifying, for your reference only, what the what the visual effect of converting an image to linear light and not back to gamma-corrected light would look like visually on a standard display, since you had been confused by the terminology I was using in my previous post.

I'll assume here that you were instead clarifying, in reference to my previous question about differences between linear error diffusion and linear scaling, that not converting the actual image to linear light is a difference which does not occur with the error diffusion routine. On the other hand, linear light scaling I'd assume must convert the image to to linear light and back, and likely why the performance overhead is higher? I didn't understand before what that part of your shader code was doing, so thank you for clarifying that.

So while you now mention that "only the error diffusion weight distributions and decisions are performed in linear light", couldn't that be the cause of linear light issues we're seeing? The concept of error diffusion being calculated in linear light for application on a gamma corrected image feels a bit odd to me. What happens if you did convert the image to linear light, perform the error diffusion dither on the linear light image, and finally convert the image back to gamma corrected light? Maybe this doesn't make any sense in relation to error diffusion though... Unrelated, but I've always found it interesting that Adobe Photoshop for example, never allows linear light filtering to be performed or applied to images unless they are in its 32bpp floating point texture format. Anyway, sleep time for me. You don't need to spend time replying to this madshi, if you think it's nonsense.

noee
16th February 2014, 00:53
"non-scientist" here....

Those LL builds don't look right here at all, too bright, almost foggy looking. GL looked good. EDA looks the best.

6233638
16th February 2014, 00:54
Three shades don't need to be blended together, they actually *should* not be blended together. From the view point of error diffusion two shades of dots are perfectly capable of reproducing any needed brightness value in between those two shades. In its purest form, error diffusion only has black and white in its palette and recreates a whole grayscale with that. So there isn't really any need to blend 3 shades together.I agree that they shouldn't be necessary - if you're using values +/- 1 then you are adding noise to the image.
But perceptually the gradient seems to be a lot more uniform when this occurs, as every step is being dithered rather than having dithered and undithered steps.

But if you allow the different shades to be 8bit steps, the result should be perfectly smooth without any visible banding.That's probably true.

madshi
16th February 2014, 01:05
What happens if you did convert the image to linear light, perform the error diffusion dither on the linear light image, and finally convert the image back to gamma corrected light?
That wouldn't work because converting back to gamma corrected light gives me floating point values again.

"non-scientist" here....

Those LL builds don't look right here at all, too bright, almost foggy looking. GL looked good. EDA looks the best.
Sounds good!

But perceptually the gradient seems to be a lot more uniform when this occurs, as every step is being dithered rather than having dithered and undithered steps.
That may be so. But you can probably achieve the same effect by simply adding noise/grain in a custom pixel shader.

-------

Here's another adaptive build, which might look a bit less random, but hopefully have the same positive aspects of the first adaptive build:

http://madshi.net/madVRadaptive2.rar

Ok, will be gone for half a day now.

leeperry
16th February 2014, 01:06
Humm, that's plain ridiculous. The AGL1 build looks so much better than NL6.....need to test again tomorrow morning but the latter looks unnecessarily grainy and unfocused compared to the AGL1 build. The LL builds still look grainy and plain ugly, I don't see how that could change with fresh eyes but we'll see :)

Shiandow
16th February 2014, 01:43
Well, I suppose I should call myself a "scientist" then. Anyway based on the images 6233638 posted I'd say that adaptive is better. In an effort to make this somewhat more objective I also tried blurring the images. This confirmed that adaptive gave the 'smoothest' gradient and that unlimited was both more noisy and too dark.

Edit: I even think a very low level of this kind of noise might be appropriate for a low-noise algorithm but let's first try and get the medium noise algorithm right.

Ver Greeneyes
16th February 2014, 02:14
madshi, I was playing around with making my own ED algorithm to get a better understanding of it, and I was wondering: when you apply the limiter, do you update the error for that pixel to reflect that or do you just diffuse the error as if it wasn't limited?

Shiandow
16th February 2014, 02:58
madshi, I was playing around with making my own ED algorithm to get a better understanding of it, and I was wondering: when you apply the limiter, do you update the error for that pixel to reflect that or do you just diffuse the error as if it wasn't limited?

From the code he posted (http://forum.doom9.org/showthread.php?p=1668300#post1668300) I'd say he did the former i.e. update the error by using the 'limited' pixel value. This seems to cause problems when limiting the pixel value makes it hard for a particular error to be distributed (see this post (http://forum.doom9.org/showthread.php?p=1668406#post1668406)), madshi solved this by forcing the error to be smaller than the difference between adjacent colour values.

Ver Greeneyes
16th February 2014, 03:16
From the code he posted (http://forum.doom9.org/showthread.php?p=1668300#post1668300) I'd say he did the former i.e. update the error by using the 'limited' pixel value. This seems to cause problems when limiting the pixel value makes it hard for a particular error to be distributed (see this post (http://forum.doom9.org/showthread.php?p=1668406#post1668406)), madshi solved this by forcing the error to be smaller than the difference between adjacent colour values.Uh, right. I even looked at that code before. I guess I thought there would be more to it than that XD

AngelGraves13
16th February 2014, 06:14
Does madvr support 64-bit MPC BE or HC yet?

rahzel
16th February 2014, 06:33
Posted this in the MPC thread because it seems to be more of an MPC issue, but hopefully someone can help me.

Anyone else having issues with MPC HC 1.7.2+ and Fullscreen Exclusive mode in MadVR? When I try to enter FSE mode on my Radeon 7750 HTPC, the bottom MPC bar stays at the bottom and it doesn't enter FSE mode. I have to exit and fullscreen it again. On my Intel system (HD4000), it switches to FSE mode every time, but I can see the bottom MPC bar stay there for a second or two, then it enters FSE. With MPC 1.7.1 and below, I have no issues at all. This also only happens with videos that have a ~1.85/1.78 AR... movies that are ~2.35+ (or have significant bars) enter FSE mode fine.

cyberbeing
16th February 2014, 07:14
That wouldn't work because converting back to gamma corrected light gives me floating point values again.

Yes, I realize it would introduce error and not make much sense for dithering if you were then required to introduce more error afterwords, I just highly suspect doing that would resolve the gamma errors near-black & near-white.

Only the error diffusion weight distributions and decisions are performed in linear light.

If you somehow gamma corrected the dither pixel results of the weight distributions and decisions after initially calculating them in linear light, it would achieve the same result (as gamma->linear->dither linear->gamma) while leaving the image in gamma corrected light the entire time. I don't have the slimmest idea how you would do this, though it must be possible considering dithering alters the RGB pixel values of an image. It just seems that if you did not desire linear light dithering to introduce gamma error on the near-black & near-white shade of the image, you would need to do something like this.

Of course you can cover the whole gradient with loads of additional noise (like the "unlimited" build does) to make it look smoother in those contrast boosted screenshots. But that's really a "cover up", IMHO. The contrast is boosted in those screenshots so much that it can't really look smooth. But if you allow the different shades to be 8bit steps, the result should be perfectly smooth without any visible banding.

This isn't necessarily the case. As far as I'm aware, the HVS is more sensitive to slight changes in texture than it is color and luminance. Even if the image is technically perfectly smooth, it won't appear so unless the texture (or lack of texture) is perceptually even across all shades. If the dithering algorithm is the proper place for this to occur, who knows, since as you mentioned:
you can probably achieve the same effect by simply adding noise/grain in a custom pixel shader

AngelGraves13
16th February 2014, 07:45
FSE mode throws off sync for me, so I disabled it. The lips don't match 100% with the audio, it's slightly off. Enough to be annoying. Turning FSE mode off fixes the issue, so I've abandoned it until it's addressed.

Also...I don't see how MPC 65-bit not working with madvr (because it's 32-bit only) is a MPC issue. I'm asking when madvr will have a 64-bit renderer so that it can be used. Get the difference?

huhn
16th February 2014, 07:50
FSE mode throws off sync for me, so I disabled it. The lips don't match 100% with the audio, it's slightly off. Enough to be annoying. Turning FSE mode off fixes the issue, so I've abandoned it until it's addressed.

Also...I don't see how MPC 65-bit not working with madvr (because it's 32-bit only) is a MPC issue. I'm asking when madvr will have a 64-bit renderer so that it can be used. Get the difference?

maybe with 1.0 but there is no real benefit to 64 bit anyway...

just use 32 bit mpc hc nothing wrong with