15 #if defined (AJALinux)
17 #elif defined (MSWindows)
18 #pragma warning(disable: 4800)
22 #define HEX16(__x__) "0x" << hex << setw(16) << setfill('0') << uint64_t(__x__) << dec
23 #define INSTP(_p_) HEX16(uint64_t(_p_))
24 #define CSCFAIL(__x__) AJA_sERROR (AJA_DebugUnit_CSC, INSTP(this) << "::" << AJAFUNC << ": " << __x__)
25 #define CSCWARN(__x__) AJA_sWARNING(AJA_DebugUnit_CSC, INSTP(this) << "::" << AJAFUNC << ": " << __x__)
26 #define CSCNOTE(__x__) AJA_sNOTICE (AJA_DebugUnit_CSC, INSTP(this) << "::" << AJAFUNC << ": " << __x__)
27 #define CSCINFO(__x__) AJA_sINFO (AJA_DebugUnit_CSC, INSTP(this) << "::" << AJAFUNC << ": " << __x__)
28 #define CSCDBG(__x__) AJA_sDEBUG (AJA_DebugUnit_CSC, INSTP(this) << "::" << AJAFUNC << ": " << __x__)
30 #define LUTFAIL(__x__) AJA_sERROR (AJA_DebugUnit_LUT, INSTP(this) << "::" << AJAFUNC << ": " << __x__)
31 #define LUTWARN(__x__) AJA_sWARNING(AJA_DebugUnit_LUT, INSTP(this) << "::" << AJAFUNC << ": " << __x__)
32 #define LUTNOTE(__x__) AJA_sNOTICE (AJA_DebugUnit_LUT, INSTP(this) << "::" << AJAFUNC << ": " << __x__)
33 #define LUTINFO(__x__) AJA_sINFO (AJA_DebugUnit_LUT, INSTP(this) << "::" << AJAFUNC << ": " << __x__)
34 #define LUTDBG(__x__) AJA_sDEBUG (AJA_DebugUnit_LUT, INSTP(this) << "::" << AJAFUNC << ": " << __x__)
70 if (IS_CHANNEL_INVALID(inChannel))
79 if (IS_CHANNEL_INVALID (inChannel))
87 if (IS_CHANNEL_INVALID(inChannel))
90 return SetLUTV2OutputBank(inChannel, inBank);
98 default:
return false;
104 if (IS_CHANNEL_INVALID(inChannel))
116 default:
return false;
122 if (IS_CHANNEL_INVALID (inChannel))
125 return GetLUTV2OutputBank(inChannel, outBank);
133 default:
return false;
139 if (IS_CHANNEL_INVALID(inChannel))
151 default:
return false;
158 return SetLUTV2HostAccessBank(inValue);
191 default:
return false;
223 default:
return false;
229 if (IS_CHANNEL_INVALID(inChannel))
232 return GetLUTV2HostAccessBank(outValue, inChannel);
260 if (IS_CHANNEL_INVALID(inChannel))
313 if (IS_CHANNEL_INVALID(inChannel))
322 if (IS_CHANNEL_INVALID(inChannel))
341 ULWord has12BitLUTSupport(0);
347 if(!Has12BitLUTSupport())
355 if(!Has12BitLUTSupport())
366 if (IS_CHANNEL_INVALID (inChannel))
413 if (IS_CHANNEL_INVALID(inChannel))
447 GetColorSpaceMethod(result, inChannel);
454 if (IS_CHANNEL_INVALID (channel))
462 if (IS_CHANNEL_INVALID(inChannel))
471 static const double kGammaMac(1.8);
472 double gamma1(0.0), gamma2(0.0), scale(0.0), fullWhite(0.0), fullBlack(0.0), smpteWhite(0.0), smpteBlack(0.0);
473 uint32_t tableSize(0);
496 outTable.reserve(tableSize);
497 while (outTable.size() < tableSize)
498 outTable.push_back(
double(0.0));
506 outTable.reserve(tableSize);
507 while (outTable.size() < tableSize)
508 outTable.push_back(
double(0.0));
512 double smpteScale = (smpteWhite - smpteBlack) - 1.0;
522 for (
size_t ndx = 0; ndx < tableSize; ndx++)
523 outTable[ndx] =
double(ndx);
530 scale = (smpteWhite - smpteBlack) / (fullWhite - fullBlack);
532 for (
size_t ndx = 0; ndx < tableSize; ndx++)
533 outTable[ndx] = (
double(ndx) * scale) + (smpteBlack - (scale * fullBlack));
537 scale = (fullWhite - fullBlack) / (smpteWhite - smpteBlack);
539 for (
size_t ndx = 0; ndx < (uint32_t)smpteBlack; ndx++)
540 outTable[ndx] = fullBlack;
542 for (
size_t ndx = (uint32_t)smpteBlack; ndx < (uint32_t)smpteWhite; ndx++)
543 outTable[ndx] = (
double(ndx) * scale) + ((uint32_t)fullBlack - (scale * (uint32_t)smpteBlack));
545 for (
size_t ndx = (uint32_t)smpteWhite; ndx < tableSize; ndx++)
546 outTable[ndx] = fullWhite;
553 gamma1 = (inBank ==
kLUTBank_RGB2YUV ? (kGammaMac / 2.2) : (2.2 / kGammaMac) );
554 for (
size_t ndx = 0; ndx < tableSize; ndx++)
555 outTable[ndx] = fullWhite * ::pow(
double(ndx) / fullWhite, gamma1);
561 gamma1 = (inBank ==
kLUTBank_RGB2YUV ? (kGammaMac / 2.2) : (2.2 / kGammaMac) );
562 for (
size_t ndx = 0; ndx < tableSize; ndx++)
564 if (ndx <= (uint32_t)smpteBlack || ndx >= (uint32_t)smpteWhite)
565 outTable[ndx] = double(ndx);
567 outTable[ndx] = smpteScale * ::pow((
double(ndx) - smpteBlack) / smpteScale, gamma1) + smpteBlack;
577 for (
size_t ndx = 0; ndx < tableSize; ndx++)
579 double f(::pow(
double(ndx) / fullWhite, gamma1));
583 outTable[ndx] = fullWhite * (f * 4.5);
585 outTable[ndx] = fullWhite * ((1.099 * ::pow(f, gamma2)) - 0.099);
591 gamma2 = 1.0 / kGammaMac;
592 for (
size_t ndx = 0; ndx < tableSize; ndx++)
594 double f(
double(ndx) / fullWhite);
599 f = ::pow((f + 0.099) / 1.099, gamma1);
602 outTable[ndx] = fullWhite * ::pow(f, gamma2);
613 for (
size_t ndx = 0; ndx < tableSize; ndx++)
615 if (ndx <= (uint32_t)smpteBlack || ndx >= (uint32_t)smpteWhite)
616 outTable[ndx] = double(ndx);
619 double f(::pow((
double(ndx) - smpteBlack) / 875.0, gamma1));
623 outTable[ndx] = smpteScale * (f * 4.5) + smpteBlack;
625 outTable[ndx] = smpteScale * ((1.099 * ::pow(f, gamma2)) - 0.099) + smpteBlack;
632 gamma2 = 1.0 / kGammaMac;
633 for (
size_t ndx = 0; ndx < tableSize; ndx++)
635 if (ndx <= (uint32_t)smpteBlack || ndx >= (uint32_t)smpteWhite)
636 outTable[ndx] = double(ndx);
639 double f ((
double(ndx) - smpteBlack) / 875.0);
644 f = ::pow((f + 0.099) / 1.099, gamma1);
647 outTable[ndx] = smpteScale * ::pow(f, gamma2) + smpteBlack;
656 static inline ULWord intClamp (
const int inMin,
const int inValue,
const int inMax)
658 return ULWord(inValue < inMin ? inMin : (inValue > inMax ? inMax : inValue));
665 uint32_t tableSize = inBitDepth ==
NTV2_LUT10Bit ? 1024 : 4096;
668 if (dblTable.size() < tableSize)
670 outTable.reserve(tableSize);
671 while (outTable.size() < tableSize)
672 outTable.push_back(0);
673 for (
size_t ndx(0); ndx < tableSize; ndx++)
675 if ((outTable.at(ndx) =
UWord(
intClamp(0,
int(dblTable.at(ndx) + 0.5), tableSize-1))))
678 if (nonzeroes >= tableSize)
680 return nonzeroes >= tableSize;
699 {
LUTFAIL(
"Size error (< 1024): R=" <<
DEC(inRedLUT.size()) <<
" G=" <<
DEC(inGreenLUT.size()) <<
" B=" <<
DEC(inBlueLUT.size()));
return false;}
701 if (IS_CHANNEL_INVALID(inLUT))
702 {
LUTFAIL(
"Bad LUT/channel (> 7): " <<
DEC(inLUT));
return false;}
704 if (inBank != 0 && inBank != 1)
705 {
LUTFAIL(
"Bad bank value (> 1): " <<
DEC(inBank));
return false;}
710 bool bResult = SetLUTEnable(
true, inLUT);
716 bResult = LoadLUTTables (inRedLUT, inGreenLUT, inBlueLUT);
717 SetLUTEnable (
false, inLUT);
726 {
LUTFAIL(
"Size error (< 4096): R=" <<
DEC(inRedLUT.size()) <<
" G=" <<
DEC(inGreenLUT.size()) <<
" B=" <<
DEC(inBlueLUT.size()));
return false;}
728 if (IS_CHANNEL_INVALID(inLUT))
729 {
LUTFAIL(
"Bad LUT/channel (> 7): " <<
DEC(inLUT));
return false;}
731 if (inBank != 0 && inBank != 1)
732 {
LUTFAIL(
"Bad bank value (> 1): " <<
DEC(inBank));
return false;}
734 if (!Has12BitLUTSupport())
740 bool bResult = SetLUTEnable(
true, inLUT);
746 bResult = Load12BitLUTTables (inRedLUT, inGreenLUT, inBlueLUT);
747 SetLUTEnable (
false, inLUT);
756 {
LUTFAIL(
"Size error (< 1024): R=" <<
DEC(inRedLUT.size()) <<
" G=" <<
DEC(inGreenLUT.size()) <<
" B=" <<
DEC(inBlueLUT.size()));
return false;}
758 if (IS_CHANNEL_INVALID(inLUT))
759 {
LUTFAIL(
"Bad LUT/channel (> 7): " <<
DEC(inLUT));
return false;}
761 if (inBank != 0 && inBank != 1)
762 {
LUTFAIL(
"Bad bank value (> 1): " <<
DEC(inBank));
return false;}
767 bool bResult = SetLUTEnable(
true, inLUT);
773 bResult = WriteLUTTables (inRedLUT, inGreenLUT, inBlueLUT);
774 SetLUTEnable (
false, inLUT);
783 {
LUTFAIL(
"Size error (< 4096): R=" <<
DEC(inRedLUT.size()) <<
" G=" <<
DEC(inGreenLUT.size()) <<
" B=" <<
DEC(inBlueLUT.size()));
return false;}
785 if (IS_CHANNEL_INVALID(inLUT))
786 {
LUTFAIL(
"Bad LUT/channel (> 7): " <<
DEC(inLUT));
return false;}
788 if (inBank != 0 && inBank != 1)
789 {
LUTFAIL(
"Bad bank value (> 1): " <<
DEC(inBank));
return false;}
791 if (!Has12BitLUTSupport())
797 bool bResult = SetLUTEnable(
true, inLUT);
803 bResult = Write12BitLUTTables (inRedLUT, inGreenLUT, inBlueLUT);
804 SetLUTEnable (
false, inLUT);
812 {
LUTFAIL(
"Size error (< 1024): R=" <<
DEC(inRedLUT.size()) <<
" G=" <<
DEC(inGreenLUT.size()) <<
" B=" <<
DEC(inBlueLUT.size()));
return false;}
820 redLUT .at(ndx) =
UWord(
intClamp(0,
int(inRedLUT [ndx] + 0.5), 1023));
821 greenLUT.at(ndx) =
UWord(
intClamp(0,
int(inGreenLUT[ndx] + 0.5), 1023));
822 blueLUT .at(ndx) =
UWord(
intClamp(0,
int(inBlueLUT [ndx] + 0.5), 1023));
824 return WriteLUTTables(redLUT, greenLUT, blueLUT);
830 {
LUTFAIL(
"Size error (< 4096): R=" <<
DEC(inRedLUT.size()) <<
" G=" <<
DEC(inGreenLUT.size()) <<
" B=" <<
DEC(inBlueLUT.size()));
return false;}
838 redLUT .at(ndx) =
UWord(
intClamp(0,
int(inRedLUT [ndx] + 0.5), 4095));
839 greenLUT.at(ndx) =
UWord(
intClamp(0,
int(inGreenLUT[ndx] + 0.5), 4095));
840 blueLUT .at(ndx) =
UWord(
intClamp(0,
int(inBlueLUT [ndx] + 0.5), 4095));
842 return Write12BitLUTTables(redLUT, greenLUT, blueLUT);
848 {
LUTFAIL(
"Size error (< 1024): R=" <<
DEC(inRedLUT.size()) <<
" G=" <<
DEC(inGreenLUT.size()) <<
" B=" <<
DEC(inBlueLUT.size()));
return false;}
850 size_t errorCount(0), nonzeroes(0);
860 ULWord loGreen =
ULWord(inGreenLUT[2 * ndx + 0]) & 0x3FF;
861 ULWord hiGreen =
ULWord(inGreenLUT[2 * ndx + 1]) & 0x3FF;
866 if(!Has12BitLUTSupport())
869 if (tmpRed) nonzeroes++;
870 if (!WriteRegister(RTableReg++, tmpRed))
874 if (tmpGreen) nonzeroes++;
875 if (!WriteRegister(GTableReg++, tmpGreen))
879 if (tmpBlue) nonzeroes++;
880 if (!WriteRegister(BTableReg++, tmpBlue))
887 if(tmpRedLo || tmpRedHi) nonzeroes++;
889 if (!WriteRegister(RTableReg++, tmpRedLo))
891 if (!WriteRegister(RTableReg++, tmpRedLo))
893 if (!WriteRegister(RTableReg++, tmpRedHi))
895 if (!WriteRegister(RTableReg++, tmpRedHi))
900 if(tmpGreenLo || tmpGreenHi) nonzeroes++;
902 if (!WriteRegister(GTableReg++, tmpGreenLo))
904 if (!WriteRegister(GTableReg++, tmpGreenLo))
906 if (!WriteRegister(GTableReg++, tmpGreenHi))
908 if (!WriteRegister(GTableReg++, tmpGreenHi))
913 if(tmpBlueLo || tmpBlueHi) nonzeroes++;
915 if (!WriteRegister(BTableReg++, tmpBlueLo))
917 if (!WriteRegister(BTableReg++, tmpBlueLo))
919 if (!WriteRegister(BTableReg++, tmpBlueHi))
921 if (!WriteRegister(BTableReg++, tmpBlueHi))
925 if (errorCount)
LUTFAIL(GetDisplayName() <<
" " <<
DEC(errorCount) <<
" WriteRegister calls failed");
926 else if (!nonzeroes)
LUTWARN(GetDisplayName() <<
" All zero LUT table values!");
933 {
LUTFAIL(
"Size error (< 4096): R=" <<
DEC(inRedLUT.size()) <<
" G=" <<
DEC(inGreenLUT.size()) <<
" B=" <<
DEC(inBlueLUT.size()));
return false;}
935 if (!Has12BitLUTSupport())
938 size_t errorCount(0), nonzeroes(0);
950 if (tmpRed) nonzeroes++;
951 if (!WriteRegister(RTableReg++, tmpRed))
958 ULWord loGreen =
ULWord(inGreenLUT[2 * ndx + 0]) & 0xFFF;
959 ULWord hiGreen =
ULWord(inGreenLUT[2 * ndx + 1]) & 0xFFF;
962 if (tmpGreen) nonzeroes++;
963 if (!WriteRegister(GTableReg++, tmpGreen))
974 if (tmpBlue) nonzeroes++;
975 if (!WriteRegister(BTableReg++, tmpBlue))
979 if (errorCount)
LUTFAIL(GetDisplayName() <<
" " <<
DEC(errorCount) <<
" WriteRegister calls failed");
980 else if (!nonzeroes)
LUTWARN(GetDisplayName() <<
" All zero LUT table values!");
991 if (!ReadLUTTables(red, green, blue))
993 if (red.size() != green.size() || green.size() != blue.size())
994 {
LUTFAIL(
"Unexpected size mismatch: R(" <<
DEC(red.size()) <<
")!=G(" <<
DEC(green.size()) <<
")!=B(" <<
DEC(blue.size()) <<
")");
return false;}
995 if (red.size() != outRedLUT.size() || green.size() != outGreenLUT.size() || blue.size() != outBlueLUT.size())
996 {
LUTFAIL(
"Unexpected size mismatch: R(" <<
DEC(red.size()) <<
")!=oR(" <<
DEC(outRedLUT.size())
997 <<
") G(" <<
DEC(green.size()) <<
")!=oG(" <<
DEC(outGreenLUT.size())
998 <<
") B(" <<
DEC(blue.size()) <<
")!=oB(" <<
DEC(outBlueLUT.size())
999 <<
")");
return false;}
1003 outRedLUT [ndx] = red[ndx];
1004 outGreenLUT[ndx] = green[ndx];
1005 outBlueLUT [ndx] = blue[ndx];
1016 if(!Has12BitLUTSupport())
1020 if (!Read12BitLUTTables(red, green, blue))
1022 if (red.size() != green.size() || green.size() != blue.size())
1023 {
LUTFAIL(
"Unexpected size mismatch: R(" <<
DEC(red.size()) <<
")!=G(" <<
DEC(green.size()) <<
")!=B(" <<
DEC(blue.size()) <<
")");
return false;}
1024 if (red.size() != outRedLUT.size() || green.size() != outGreenLUT.size() || blue.size() != outBlueLUT.size())
1025 {
LUTFAIL(
"Unexpected size mismatch: R(" <<
DEC(red.size()) <<
")!=oR(" <<
DEC(outRedLUT.size())
1026 <<
") G(" <<
DEC(green.size()) <<
")!=oG(" <<
DEC(outGreenLUT.size())
1027 <<
") B(" <<
DEC(blue.size()) <<
")!=oB(" <<
DEC(outBlueLUT.size())
1028 <<
")");
return false;}
1032 outRedLUT [ndx] = red[ndx];
1033 outGreenLUT[ndx] = green[ndx];
1034 outBlueLUT [ndx] = blue[ndx];
1044 size_t errors(0), nonzeroes(0);
1053 if (!ReadRegister(RTableReg++, temp))
1057 if (temp) nonzeroes++;
1059 if (!ReadRegister(GTableReg++, temp))
1063 if (temp) nonzeroes++;
1065 if (!ReadRegister(BTableReg++, temp))
1069 if (temp) nonzeroes++;
1071 if (errors)
LUTFAIL(GetDisplayName() <<
" " <<
DEC(errors) <<
" ReadRegister calls failed");
1072 else if (!nonzeroes)
LUTWARN(GetDisplayName() <<
" All zero LUT table values!");
1081 size_t errors(0), nonzeroes(0);
1083 if(!Has12BitLUTSupport())
1094 if (!ReadRegister(RTableReg++, temp))
1098 if (temp) nonzeroes++;
1105 if (!ReadRegister(GTableReg++, temp))
1109 if (temp) nonzeroes++;
1116 if (!ReadRegister(BTableReg++, temp))
1120 if (temp) nonzeroes++;
1123 if (errors)
LUTFAIL(GetDisplayName() <<
" " <<
DEC(errors) <<
" ReadRegister calls failed");
1124 else if (!nonzeroes)
LUTWARN(GetDisplayName() <<
" All zero LUT table values!");
1134 static const UWord BitCountNibble[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
1136 if (IS_CHANNEL_INVALID(inLUT))
1137 {
LUTFAIL(
"Bad LUT number (> 7): " <<
DEC(inLUT));
return false;}
1142 const ULWord mask(LUTEnableMasks[inLUT]), shift(LUTEnableShifts[inLUT]);
ULWord tmp(0);
1144 if (((tmp & mask)?
true:
false) == inEnable)
1145 LUTWARN(GetDisplayName() <<
" V2 LUT" <<
DEC(inLUT+1) <<
" Enable bit already " << (inEnable?
"set":
"clear"));
1148 if (BitCountNibble[tmp & 0xF] || BitCountNibble[(tmp >> 4) & 0xF])
1149 LUTWARN(GetDisplayName() <<
" Setting V2 LUT" <<
DEC(inLUT+1) <<
" Enable bit: multiple Enable bits set: " <<
xHEX0N(tmp,4));
1153 {
LUTFAIL(GetDisplayName() <<
" WriteRegister kRegLUTV2Control failed, enable=" <<
DEC(
UWord(inEnable)));
return false;}
1159 LUTWARN(GetDisplayName() <<
" Clearing V2 LUT" <<
DEC(inLUT+1) <<
" Enable bit: still has Enable bit(s) set: " <<
xHEX0N(tmp,4));
1167 if (IS_CHANNEL_INVALID (inChannel))
1177 if (IS_CHANNEL_INVALID (inChannel))
1188 if (IS_CHANNEL_INVALID (inChannel))
1195 return !IS_CHANNEL_INVALID(inChannel)
1201 return !IS_CHANNEL_INVALID(inChannel)
1207 return !IS_CHANNEL_INVALID(inChannel)
1213 if (IS_CHANNEL_INVALID(inChannel))
1230 if (IS_CHANNEL_INVALID (inChannel))
1254 if (IS_CHANNEL_INVALID (inChannel))
1296 if (IS_CHANNEL_INVALID (inChannel))
1299 ULWord regVal(0), MSBs(0), LSBs(0);
1303 LSBs = (regVal >> 11) & 0x00000003;
1304 MSBs = regVal & 0x000007FF;
1310 LSBs = (regVal >> 11) & 0x00000003;
1311 MSBs = regVal & 0x000007FF;
1317 LSBs = (regVal >> 11) & 0x00000003;
1318 MSBs = regVal & 0x000007FF;
1324 LSBs = (regVal >> 11) & 0x00000003;
1325 MSBs = regVal & 0x000007FF;
1331 LSBs = (regVal >> 11) & 0x00000003;
1332 MSBs = regVal & 0x000007FF;
1342 outVideoKeySyncFail = (value == 1);
1354 if (!GenerateGammaTable(inLUTType, inBank, table))
1356 ::memcpy(pOutTable, &table[0], table.size() *
sizeof(
double));
1363 if (IS_CHANNEL_INVALID (inChannel))
1369 if (inBank != 0 && inBank != 1)
1375 bool bResult = SetLUTEnable (
true, inChannel);
1381 bResult = LoadLUTTable (pInTable);
1382 SetLUTEnable (
false, inChannel);
1396 rgbLUT.push_back(pInTable[ndx]);
1399 return LoadLUTTables(rgbLUT, rgbLUT, rgbLUT);
1408 bool quadEnabled(
false), quadQuadEnabled(
false);
1412 actualFrameSize *= 4;
1413 if (quadQuadEnabled)
1414 actualFrameSize *= 4;
1415 ULWord lutTableLocation (((actualFrameSize * inFrameNumber)/4) + LUTTableIndexOffset/4);
1431 bool quadEnabled(
false), quadQuadEnabled(
false);
1435 actualFrameSize *= 4;
1436 if (quadQuadEnabled)
1437 actualFrameSize *= 4;
1438 ULWord lutTableLocation (((actualFrameSize * inFrameNumber)/4) + LUTTableIndexOffset/4);
1452 #pragma warning(default: 4800)