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__)
102 if (IS_CHANNEL_INVALID(inChannel))
111 if (IS_CHANNEL_INVALID (inChannel))
119 if (IS_CHANNEL_INVALID(inChannel))
122 return SetLUTV2OutputBank(inChannel, inBank);
124 return SetLUTV3OutputBank(inChannel, inBank);
133 default:
return false;
139 if (IS_CHANNEL_INVALID(inChannel))
151 default:
return false;
159 if (IS_CHANNEL_INVALID(inChannel))
172 if (IS_CHANNEL_INVALID (inChannel))
175 return GetLUTV2OutputBank(inChannel, outBank);
177 return GetLUTV3OutputBank(inChannel, outBank);
186 default:
return false;
192 if (IS_CHANNEL_INVALID(inChannel))
204 default:
return false;
212 if (IS_CHANNEL_INVALID(inChannel))
224 return SetLUTV2HostAccessBank(inValue);
226 return SetLUTV3HostAccessBank(inValue);
259 default:
return false;
291 default:
return false;
327 default:
return false;
341 if (IS_CHANNEL_INVALID(inChannel))
344 return GetLUTV2HostAccessBank(outValue, inChannel);
346 return GetLUTV3HostAccessBank(outValue, inChannel);
374 if (IS_CHANNEL_INVALID(inChannel))
429 if (IS_CHANNEL_INVALID(inChannel))
440 if (IS_CHANNEL_INVALID(inChannel))
449 if (IS_CHANNEL_INVALID(inChannel))
468 ULWord has12BitLUTSupport(0);
481 (has12BitLUTSupport ?
true :
false);
493 if(!Has12BitLUTSupport())
528 if(!Has12BitLUTSupport())
555 if (IS_CHANNEL_INVALID (inChannel))
602 if (IS_CHANNEL_INVALID(inChannel))
636 GetColorSpaceMethod(result, inChannel);
643 if (IS_CHANNEL_INVALID (channel))
651 if (IS_CHANNEL_INVALID(inChannel))
660 static const double kGammaMac(1.8);
661 double gamma1(0.0), gamma2(0.0), scale(0.0), fullWhite(0.0), fullBlack(0.0), smpteWhite(0.0), smpteBlack(0.0);
662 uint32_t tableSize(0);
685 outTable.reserve(tableSize);
686 while (outTable.size() < tableSize)
687 outTable.push_back(
double(0.0));
695 outTable.reserve(tableSize);
696 while (outTable.size() < tableSize)
697 outTable.push_back(
double(0.0));
701 double smpteScale = (smpteWhite - smpteBlack) - 1.0;
711 for (
size_t ndx = 0; ndx < tableSize; ndx++)
712 outTable[ndx] =
double(ndx);
719 scale = (smpteWhite - smpteBlack) / (fullWhite - fullBlack);
721 for (
size_t ndx = 0; ndx < tableSize; ndx++)
722 outTable[ndx] = (
double(ndx) * scale) + (smpteBlack - (scale * fullBlack));
726 scale = (fullWhite - fullBlack) / (smpteWhite - smpteBlack);
728 for (
size_t ndx = 0; ndx < (uint32_t)smpteBlack; ndx++)
729 outTable[ndx] = fullBlack;
731 for (
size_t ndx = (uint32_t)smpteBlack; ndx < (uint32_t)smpteWhite; ndx++)
732 outTable[ndx] = (
double(ndx) * scale) + ((uint32_t)fullBlack - (scale * (uint32_t)smpteBlack));
734 for (
size_t ndx = (uint32_t)smpteWhite; ndx < tableSize; ndx++)
735 outTable[ndx] = fullWhite;
742 gamma1 = (inBank ==
kLUTBank_RGB2YUV ? (kGammaMac / 2.2) : (2.2 / kGammaMac) );
743 for (
size_t ndx = 0; ndx < tableSize; ndx++)
744 outTable[ndx] = fullWhite * ::pow(
double(ndx) / fullWhite, gamma1);
750 gamma1 = (inBank ==
kLUTBank_RGB2YUV ? (kGammaMac / 2.2) : (2.2 / kGammaMac) );
751 for (
size_t ndx = 0; ndx < tableSize; ndx++)
753 if (ndx <= (uint32_t)smpteBlack || ndx >= (uint32_t)smpteWhite)
754 outTable[ndx] = double(ndx);
756 outTable[ndx] = smpteScale * ::pow((
double(ndx) - smpteBlack) / smpteScale, gamma1) + smpteBlack;
766 for (
size_t ndx = 0; ndx < tableSize; ndx++)
768 double f(::pow(
double(ndx) / fullWhite, gamma1));
772 outTable[ndx] = fullWhite * (f * 4.5);
774 outTable[ndx] = fullWhite * ((1.099 * ::pow(f, gamma2)) - 0.099);
780 gamma2 = 1.0 / kGammaMac;
781 for (
size_t ndx = 0; ndx < tableSize; ndx++)
783 double f(
double(ndx) / fullWhite);
788 f = ::pow((f + 0.099) / 1.099, gamma1);
791 outTable[ndx] = fullWhite * ::pow(f, gamma2);
802 for (
size_t ndx = 0; ndx < tableSize; ndx++)
804 if (ndx <= (uint32_t)smpteBlack || ndx >= (uint32_t)smpteWhite)
805 outTable[ndx] = double(ndx);
808 double f(::pow((
double(ndx) - smpteBlack) / 875.0, gamma1));
812 outTable[ndx] = smpteScale * (f * 4.5) + smpteBlack;
814 outTable[ndx] = smpteScale * ((1.099 * ::pow(f, gamma2)) - 0.099) + smpteBlack;
821 gamma2 = 1.0 / kGammaMac;
822 for (
size_t ndx = 0; ndx < tableSize; ndx++)
824 if (ndx <= (uint32_t)smpteBlack || ndx >= (uint32_t)smpteWhite)
825 outTable[ndx] = double(ndx);
828 double f ((
double(ndx) - smpteBlack) / 875.0);
833 f = ::pow((f + 0.099) / 1.099, gamma1);
836 outTable[ndx] = smpteScale * ::pow(f, gamma2) + smpteBlack;
845 static inline ULWord intClamp (
const int inMin,
const int inValue,
const int inMax)
847 return ULWord(inValue < inMin ? inMin : (inValue > inMax ? inMax : inValue));
854 uint32_t tableSize = inBitDepth ==
NTV2_LUT10Bit ? 1024 : 4096;
857 if (dblTable.size() < tableSize)
859 outTable.reserve(tableSize);
860 while (outTable.size() < tableSize)
861 outTable.push_back(0);
862 for (
size_t ndx(0); ndx < tableSize; ndx++)
864 if ((outTable.at(ndx) =
UWord(
intClamp(0,
int(dblTable.at(ndx) + 0.5), tableSize-1))))
867 if (nonzeroes >= tableSize)
869 return nonzeroes >= tableSize;
888 {
LUTFAIL(
"Size error (< 1024): R=" <<
DEC(inRedLUT.size()) <<
" G=" <<
DEC(inGreenLUT.size()) <<
" B=" <<
DEC(inBlueLUT.size()));
return false;}
890 if (IS_CHANNEL_INVALID(inLUT))
891 {
LUTFAIL(
"Bad LUT/channel (> 7): " <<
DEC(inLUT));
return false;}
893 if (inBank != 0 && inBank != 1)
894 {
LUTFAIL(
"Bad bank value (> 1): " <<
DEC(inBank));
return false;}
899 bool bResult = SetLUTEnable(
true, inLUT);
905 bResult = LoadLUTTables (inRedLUT, inGreenLUT, inBlueLUT);
906 SetLUTEnable (
false, inLUT);
915 {
LUTFAIL(
"Size error (< 4096): R=" <<
DEC(inRedLUT.size()) <<
" G=" <<
DEC(inGreenLUT.size()) <<
" B=" <<
DEC(inBlueLUT.size()));
return false;}
917 if (IS_CHANNEL_INVALID(inLUT))
918 {
LUTFAIL(
"Bad LUT/channel (> 7): " <<
DEC(inLUT));
return false;}
920 if (inBank != 0 && inBank != 1)
921 {
LUTFAIL(
"Bad bank value (> 1): " <<
DEC(inBank));
return false;}
923 if (!Has12BitLUTSupport())
929 bool bResult = SetLUTEnable(
true, inLUT);
935 bResult = Load12BitLUTTables (inRedLUT, inGreenLUT, inBlueLUT);
936 SetLUTEnable (
false, inLUT);
945 {
LUTFAIL(
"Size error (< 1024): R=" <<
DEC(inRedLUT.size()) <<
" G=" <<
DEC(inGreenLUT.size()) <<
" B=" <<
DEC(inBlueLUT.size()));
return false;}
947 if (IS_CHANNEL_INVALID(inLUT))
948 {
LUTFAIL(
"Bad LUT/channel (> 7): " <<
DEC(inLUT));
return false;}
950 if (inBank != 0 && inBank != 1)
951 {
LUTFAIL(
"Bad bank value (> 1): " <<
DEC(inBank));
return false;}
956 bool bResult = SetLUTEnable(
true, inLUT);
962 bResult = WriteLUTTables (inRedLUT, inGreenLUT, inBlueLUT);
963 SetLUTEnable (
false, inLUT);
972 {
LUTFAIL(
"Size error (< 4096): R=" <<
DEC(inRedLUT.size()) <<
" G=" <<
DEC(inGreenLUT.size()) <<
" B=" <<
DEC(inBlueLUT.size()));
return false;}
974 if (IS_CHANNEL_INVALID(inLUT))
975 {
LUTFAIL(
"Bad LUT/channel (> 7): " <<
DEC(inLUT));
return false;}
977 if (inBank != 0 && inBank != 1)
978 {
LUTFAIL(
"Bad bank value (> 1): " <<
DEC(inBank));
return false;}
980 if (!Has12BitLUTSupport())
986 bool bResult = SetLUTEnable(
true, inLUT);
992 bResult = Write12BitLUTTables (inRedLUT, inGreenLUT, inBlueLUT);
993 SetLUTEnable (
false, inLUT);
1001 {
LUTFAIL(
"Size error (< 1024): R=" <<
DEC(inRedLUT.size()) <<
" G=" <<
DEC(inGreenLUT.size()) <<
" B=" <<
DEC(inBlueLUT.size()));
return false;}
1009 redLUT .at(ndx) =
UWord(
intClamp(0,
int(inRedLUT [ndx] + 0.5), 1023));
1010 greenLUT.at(ndx) =
UWord(
intClamp(0,
int(inGreenLUT[ndx] + 0.5), 1023));
1011 blueLUT .at(ndx) =
UWord(
intClamp(0,
int(inBlueLUT [ndx] + 0.5), 1023));
1013 return WriteLUTTables(redLUT, greenLUT, blueLUT);
1019 {
LUTFAIL(
"Size error (< 4096): R=" <<
DEC(inRedLUT.size()) <<
" G=" <<
DEC(inGreenLUT.size()) <<
" B=" <<
DEC(inBlueLUT.size()));
return false;}
1027 redLUT .at(ndx) =
UWord(
intClamp(0,
int(inRedLUT [ndx] + 0.5), 4095));
1028 greenLUT.at(ndx) =
UWord(
intClamp(0,
int(inGreenLUT[ndx] + 0.5), 4095));
1029 blueLUT .at(ndx) =
UWord(
intClamp(0,
int(inBlueLUT [ndx] + 0.5), 4095));
1031 return Write12BitLUTTables(redLUT, greenLUT, blueLUT);
1037 {
LUTFAIL(
"Size error (< 1024): R=" <<
DEC(inRedLUT.size()) <<
" G=" <<
DEC(inGreenLUT.size()) <<
" B=" <<
DEC(inBlueLUT.size()));
return false;}
1039 size_t errorCount(0), nonzeroes(0);
1049 ULWord loGreen =
ULWord(inGreenLUT[2 * ndx + 0]) & 0x3FF;
1050 ULWord hiGreen =
ULWord(inGreenLUT[2 * ndx + 1]) & 0x3FF;
1052 ULWord loBlue =
ULWord(inBlueLUT[2 * ndx + 0]) & 0x3FF;
1053 ULWord hiBlue =
ULWord(inBlueLUT[2 * ndx + 1]) & 0x3FF;
1055 if(!Has12BitLUTSupport())
1058 if (tmpRed) nonzeroes++;
1059 if (!WriteRegister(RTableReg++, tmpRed))
1063 if (tmpGreen) nonzeroes++;
1064 if (!WriteRegister(GTableReg++, tmpGreen))
1068 if (tmpBlue) nonzeroes++;
1069 if (!WriteRegister(BTableReg++, tmpBlue))
1076 if(tmpRedLo || tmpRedHi) nonzeroes++;
1078 if (!WriteRegister(RTableReg++, tmpRedLo))
1080 if (!WriteRegister(RTableReg++, tmpRedLo))
1082 if (!WriteRegister(RTableReg++, tmpRedHi))
1084 if (!WriteRegister(RTableReg++, tmpRedHi))
1089 if(tmpGreenLo || tmpGreenHi) nonzeroes++;
1091 if (!WriteRegister(GTableReg++, tmpGreenLo))
1093 if (!WriteRegister(GTableReg++, tmpGreenLo))
1095 if (!WriteRegister(GTableReg++, tmpGreenHi))
1097 if (!WriteRegister(GTableReg++, tmpGreenHi))
1102 if(tmpBlueLo || tmpBlueHi) nonzeroes++;
1104 if (!WriteRegister(BTableReg++, tmpBlueLo))
1106 if (!WriteRegister(BTableReg++, tmpBlueLo))
1108 if (!WriteRegister(BTableReg++, tmpBlueHi))
1110 if (!WriteRegister(BTableReg++, tmpBlueHi))
1114 if (errorCount)
LUTFAIL(GetDisplayName() <<
" " <<
DEC(errorCount) <<
" WriteRegister calls failed");
1115 else if (!nonzeroes)
LUTWARN(GetDisplayName() <<
" All zero LUT table values!");
1122 {
LUTFAIL(
"Size error (< 4096): R=" <<
DEC(inRedLUT.size()) <<
" G=" <<
DEC(inGreenLUT.size()) <<
" B=" <<
DEC(inBlueLUT.size()));
return false;}
1124 if (!Has12BitLUTSupport())
1127 size_t errorCount(0), nonzeroes(0);
1139 if (tmpRed) nonzeroes++;
1140 if (!WriteRegister(RTableReg++, tmpRed))
1147 ULWord loGreen =
ULWord(inGreenLUT[2 * ndx + 0]) & 0xFFF;
1148 ULWord hiGreen =
ULWord(inGreenLUT[2 * ndx + 1]) & 0xFFF;
1151 if (tmpGreen) nonzeroes++;
1152 if (!WriteRegister(GTableReg++, tmpGreen))
1159 ULWord loBlue =
ULWord(inBlueLUT[2 * ndx + 0]) & 0xFFF;
1160 ULWord hiBlue =
ULWord(inBlueLUT[2 * ndx + 1]) & 0xFFF;
1163 if (tmpBlue) nonzeroes++;
1164 if (!WriteRegister(BTableReg++, tmpBlue))
1168 if (errorCount)
LUTFAIL(GetDisplayName() <<
" " <<
DEC(errorCount) <<
" WriteRegister calls failed");
1169 else if (!nonzeroes)
LUTWARN(GetDisplayName() <<
" All zero LUT table values!");
1180 if (!ReadLUTTables(red, green, blue))
1182 if (red.size() != green.size() || green.size() != blue.size())
1183 {
LUTFAIL(
"Unexpected size mismatch: R(" <<
DEC(red.size()) <<
")!=G(" <<
DEC(green.size()) <<
")!=B(" <<
DEC(blue.size()) <<
")");
return false;}
1184 if (red.size() != outRedLUT.size() || green.size() != outGreenLUT.size() || blue.size() != outBlueLUT.size())
1185 {
LUTFAIL(
"Unexpected size mismatch: R(" <<
DEC(red.size()) <<
")!=oR(" <<
DEC(outRedLUT.size())
1186 <<
") G(" <<
DEC(green.size()) <<
")!=oG(" <<
DEC(outGreenLUT.size())
1187 <<
") B(" <<
DEC(blue.size()) <<
")!=oB(" <<
DEC(outBlueLUT.size())
1188 <<
")");
return false;}
1192 outRedLUT [ndx] = red[ndx];
1193 outGreenLUT[ndx] = green[ndx];
1194 outBlueLUT [ndx] = blue[ndx];
1205 if(!Has12BitLUTSupport())
1209 if (!Read12BitLUTTables(red, green, blue))
1211 if (red.size() != green.size() || green.size() != blue.size())
1212 {
LUTFAIL(
"Unexpected size mismatch: R(" <<
DEC(red.size()) <<
")!=G(" <<
DEC(green.size()) <<
")!=B(" <<
DEC(blue.size()) <<
")");
return false;}
1213 if (red.size() != outRedLUT.size() || green.size() != outGreenLUT.size() || blue.size() != outBlueLUT.size())
1214 {
LUTFAIL(
"Unexpected size mismatch: R(" <<
DEC(red.size()) <<
")!=oR(" <<
DEC(outRedLUT.size())
1215 <<
") G(" <<
DEC(green.size()) <<
")!=oG(" <<
DEC(outGreenLUT.size())
1216 <<
") B(" <<
DEC(blue.size()) <<
")!=oB(" <<
DEC(outBlueLUT.size())
1217 <<
")");
return false;}
1221 outRedLUT [ndx] = red[ndx];
1222 outGreenLUT[ndx] = green[ndx];
1223 outBlueLUT [ndx] = blue[ndx];
1233 size_t errors(0), nonzeroes(0);
1242 if (!ReadRegister(RTableReg++, temp))
1246 if (temp) nonzeroes++;
1248 if (!ReadRegister(GTableReg++, temp))
1252 if (temp) nonzeroes++;
1254 if (!ReadRegister(BTableReg++, temp))
1258 if (temp) nonzeroes++;
1260 if (errors)
LUTFAIL(GetDisplayName() <<
" " <<
DEC(errors) <<
" ReadRegister calls failed");
1261 else if (!nonzeroes)
LUTWARN(GetDisplayName() <<
" All zero LUT table values!");
1270 size_t errors(0), nonzeroes(0);
1272 if(!Has12BitLUTSupport())
1283 if (!ReadRegister(RTableReg++, temp))
1287 if (temp) nonzeroes++;
1294 if (!ReadRegister(GTableReg++, temp))
1298 if (temp) nonzeroes++;
1305 if (!ReadRegister(BTableReg++, temp))
1309 if (temp) nonzeroes++;
1312 if (errors)
LUTFAIL(GetDisplayName() <<
" " <<
DEC(errors) <<
" ReadRegister calls failed");
1313 else if (!nonzeroes)
LUTWARN(GetDisplayName() <<
" All zero LUT table values!");
1323 static const UWord BitCountNibble[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
1326 if (IS_CHANNEL_INVALID(inLUT))
1327 {
LUTFAIL(
"Bad LUT number (> 7): " <<
DEC(inLUT));
return false;}
1342 const ULWord mask(LUTEnableMasks[inLUT]), shift(LUTEnableShifts[inLUT]);
ULWord tmp(0);
1344 if (((tmp & mask)?
true:
false) == inEnable)
1345 LUTWARN(GetDisplayName() <<
" V2 LUT" <<
DEC(inLUT+1) <<
" Enable bit already " << (inEnable?
"set":
"clear"));
1348 if (BitCountNibble[tmp & 0xF] || BitCountNibble[(tmp >> 4) & 0xF])
1349 LUTWARN(GetDisplayName() <<
" Setting V2 LUT" <<
DEC(inLUT+1) <<
" Enable bit: multiple Enable bits set: " <<
xHEX0N(tmp,4));
1353 {
LUTFAIL(GetDisplayName() <<
" WriteRegister kRegLUTV2Control failed, enable=" <<
DEC(
UWord(inEnable)));
return false;}
1359 LUTWARN(GetDisplayName() <<
" Clearing V2 LUT" <<
DEC(inLUT+1) <<
" Enable bit: still has Enable bit(s) set: " <<
xHEX0N(tmp,4));
1368 if (IS_CHANNEL_INVALID (inChannel))
1378 if (IS_CHANNEL_INVALID (inChannel))
1389 if (IS_CHANNEL_INVALID (inChannel))
1396 return !IS_CHANNEL_INVALID(inChannel)
1402 return !IS_CHANNEL_INVALID(inChannel)
1408 return !IS_CHANNEL_INVALID(inChannel)
1414 if (IS_CHANNEL_INVALID(inChannel))
1431 if (IS_CHANNEL_INVALID (inChannel))
1455 if (IS_CHANNEL_INVALID (inChannel))
1497 if (IS_CHANNEL_INVALID (inChannel))
1500 ULWord regVal(0), MSBs(0), LSBs(0);
1504 LSBs = (regVal >> 11) & 0x00000003;
1505 MSBs = regVal & 0x000007FF;
1511 LSBs = (regVal >> 11) & 0x00000003;
1512 MSBs = regVal & 0x000007FF;
1518 LSBs = (regVal >> 11) & 0x00000003;
1519 MSBs = regVal & 0x000007FF;
1525 LSBs = (regVal >> 11) & 0x00000003;
1526 MSBs = regVal & 0x000007FF;
1532 LSBs = (regVal >> 11) & 0x00000003;
1533 MSBs = regVal & 0x000007FF;
1543 outVideoKeySyncFail = (value == 1);
1555 if (!GenerateGammaTable(inLUTType, inBank, table))
1557 ::memcpy(pOutTable, &table[0], table.size() *
sizeof(
double));
1564 if (IS_CHANNEL_INVALID (inChannel))
1570 if (inBank != 0 && inBank != 1)
1576 bool bResult = SetLUTEnable (
true, inChannel);
1582 bResult = LoadLUTTable (pInTable);
1583 SetLUTEnable (
false, inChannel);
1597 rgbLUT.push_back(pInTable[ndx]);
1600 return LoadLUTTables(rgbLUT, rgbLUT, rgbLUT);
1609 bool quadEnabled(
false), quadQuadEnabled(
false);
1613 actualFrameSize *= 4;
1614 if (quadQuadEnabled)
1615 actualFrameSize *= 4;
1616 ULWord lutTableLocation (((actualFrameSize * inFrameNumber)/4) + LUTTableIndexOffset/4);
1632 bool quadEnabled(
false), quadQuadEnabled(
false);
1636 actualFrameSize *= 4;
1637 if (quadQuadEnabled)
1638 actualFrameSize *= 4;
1639 ULWord lutTableLocation (((actualFrameSize * inFrameNumber)/4) + LUTTableIndexOffset/4);
1642 bool result =
false;
1662 bool result =
false;
1686 #pragma warning(default: 4800)