13 #if defined(AJA_LINUX) 21 #define LOGGING_ANCDATA AJADebug::IsActive(AJA_DebugUnit_AJAAncData) 22 #define LOGGING_ANC2110RX AJADebug::IsActive(AJA_DebugUnit_Anc2110Rcv) 23 #define LOGGING_ANC2110TX AJADebug::IsActive(AJA_DebugUnit_Anc2110Xmit) 25 #define LOGMYERROR(__x__) {if (LOGGING_ANCDATA) AJA_sERROR (AJA_DebugUnit_AJAAncData, AJAFUNC << ": " << __x__);} 26 #define LOGMYWARN(__x__) {if (LOGGING_ANCDATA) AJA_sWARNING(AJA_DebugUnit_AJAAncData, AJAFUNC << ": " << __x__);} 27 #define LOGMYNOTE(__x__) {if (LOGGING_ANCDATA) AJA_sNOTICE (AJA_DebugUnit_AJAAncData, AJAFUNC << ": " << __x__);} 28 #define LOGMYINFO(__x__) {if (LOGGING_ANCDATA) AJA_sINFO (AJA_DebugUnit_AJAAncData, AJAFUNC << ": " << __x__);} 29 #define LOGMYDEBUG(__x__) {if (LOGGING_ANCDATA) AJA_sDEBUG (AJA_DebugUnit_AJAAncData, AJAFUNC << ": " << __x__);} 31 #define RCV2110ERR(__x__) {if (LOGGING_ANC2110RX) AJA_sERROR (AJA_DebugUnit_Anc2110Rcv, AJAFUNC << ": " << __x__);} 32 #define RCV2110WARN(__x__) {if (LOGGING_ANC2110RX) AJA_sWARNING(AJA_DebugUnit_Anc2110Rcv, AJAFUNC << ": " << __x__);} 33 #define RCV2110NOTE(__x__) {if (LOGGING_ANC2110RX) AJA_sNOTICE (AJA_DebugUnit_Anc2110Rcv, AJAFUNC << ": " << __x__);} 34 #define RCV2110INFO(__x__) {if (LOGGING_ANC2110RX) AJA_sINFO (AJA_DebugUnit_Anc2110Rcv, AJAFUNC << ": " << __x__);} 35 #define RCV2110DBG(__x__) {if (LOGGING_ANC2110RX) AJA_sDEBUG (AJA_DebugUnit_Anc2110Rcv, AJAFUNC << ": " << __x__);} 37 #define XMT2110ERR(__x__) {if (LOGGING_ANC2110TX) AJA_sERROR (AJA_DebugUnit_Anc2110Xmit, AJAFUNC << ": " << __x__);} 38 #define XMT2110WARN(__x__) {if (LOGGING_ANC2110TX) AJA_sWARNING(AJA_DebugUnit_Anc2110Xmit, AJAFUNC << ": " << __x__);} 39 #define XMT2110NOTE(__x__) {if (LOGGING_ANC2110TX) AJA_sNOTICE (AJA_DebugUnit_Anc2110Xmit, AJAFUNC << ": " << __x__);} 40 #define XMT2110INFO(__x__) {if (LOGGING_ANC2110TX) AJA_sINFO (AJA_DebugUnit_Anc2110Xmit, AJAFUNC << ": " << __x__);} 41 #define XMT2110DBG(__x__) {if (LOGGING_ANC2110TX) AJA_sDEBUG (AJA_DebugUnit_Anc2110Xmit, AJAFUNC << ": " << __x__);} 43 #if defined(AJA_WINDOWS) 44 const size_t sENDL(2);
46 const size_t sENDL(1);
50 #if 0 // DetailedDebugging 51 #define RCV2110DDBG(__x__) RCV2110DBG(__x__) 52 #define XMT2110DDBG(__x__) XMT2110DBG(__x__) 54 #define RCV2110DDBG(__x__) 55 #define XMT2110DDBG(__x__) 58 #if defined(AJAHostIsBigEndian) 60 #define AJA_ENDIAN_16NtoH(__val__) (__val__) 61 #define AJA_ENDIAN_16HtoN(__val__) (__val__) 62 #define AJA_ENDIAN_32NtoH(__val__) (__val__) 63 #define AJA_ENDIAN_32HtoN(__val__) (__val__) 64 #define AJA_ENDIAN_64NtoH(__val__) (__val__) 65 #define AJA_ENDIAN_64HtoN(__val__) (__val__) 68 #define AJA_ENDIAN_16NtoH(__val__) AJA_ENDIAN_SWAP16(__val__) 69 #define AJA_ENDIAN_16HtoN(__val__) AJA_ENDIAN_SWAP16(__val__) 70 #define AJA_ENDIAN_32NtoH(__val__) AJA_ENDIAN_SWAP32(__val__) 71 #define AJA_ENDIAN_32HtoN(__val__) AJA_ENDIAN_SWAP32(__val__) 72 #define AJA_ENDIAN_64NtoH(__val__) AJA_ENDIAN_SWAP64(__val__) 73 #define AJA_ENDIAN_64HtoN(__val__) AJA_ENDIAN_SWAP64(__val__) 87 #endif // defined(_DEBUG) 96 #endif // defined(_DEBUG) 105 #endif // defined(_DEBUG) 115 #endif // defined(_DEBUG) 126 #endif // defined(_DEBUG) 140 m_rcvDataValid =
false;
177 m_payload.reserve(numBytes);
178 for (uint32_t ndx(0); ndx < numBytes; ndx++)
179 m_payload.push_back(0);
182 catch(
const bad_alloc &)
215 m_checksum = inChecksum;
217 if (inChecksum != Calculate8BitChecksum())
226 return uint16_t(GetLocationDataStream());
228 return uint16_t(GetLocationVideoLink());
240 sum += uint8_t(m_payload.size());
241 if (!m_payload.empty())
242 for (ByteVector::size_type ndx(0); ndx < m_payload.size(); ndx++)
243 sum += m_payload[ndx];
244 NTV2_ASSERT(sum == uint8_t(Calculate9BitChecksum()));
252 uint16_t sum (AddEvenParity(m_DID));
253 sum += AddEvenParity(m_SID);
254 sum += AddEvenParity(
UByte(GetDC()));
255 if (!m_payload.empty())
256 for (ByteVector::size_type ndx(0); ndx < m_payload.size(); ndx++)
257 sum += AddEvenParity(m_payload[ndx]);
259 const bool b8 ((sum & 0x100) != 0);
261 return (sum & 0x1FF) | (b9 ? 0x200 : 0x000);
290 m_location.SetDataLink(inLinkValue);
302 m_location.SetDataStream(inStream);
314 m_location.SetDataChannel(inChannel);
324 m_location.SetLineNumber(inLineNum);
334 m_location.SetHorizontalOffset(inOffset);
345 m_coding = inCodingType;
356 if (pInData ==
NULL || inNumBytes == 0)
360 AJAStatus status (AllocDataMemory(inNumBytes));
365 ::memcpy (&m_payload[0], pInData, inNumBytes);
377 const uint32_t payloadByteCount (uint32_t(pInData[5] & 0x00FF));
378 if ((inNumWords - 7) > payloadByteCount)
382 const AJAStatus status (AllocDataMemory(payloadByteCount));
387 for (uint32_t numWord (0); numWord < payloadByteCount; numWord++)
388 m_payload[numWord] =
UByte(pInData[6+numWord] & 0x00FF);
391 SetDataLocation(inLocInfo);
392 SetChecksum(
UByte(pInData[6+payloadByteCount] & 0x00FF));
393 SetDID(
UByte(pInData[3] & 0x00FF));
394 SetSID(
UByte(pInData[4] & 0x00FF));
406 if (pInData ==
NULL || inNumBytes == 0)
411 for (uint32_t ndx(0); ndx < inNumBytes; ndx++)
412 m_payload.push_back(pInData[ndx]);
414 catch(
const bad_alloc &)
432 for (uint32_t ndx(0); ndx < numBytes; ndx++)
433 m_payload.push_back(pInData[ndx]);
435 catch(
const bad_alloc &)
449 if (pOutData ==
NULL)
455 ::memcpy (pOutData, GetPayloadData(), inNumBytes);
463 const UWordSequence::size_type origSize (outUDWs.size());
466 const uint16_t UDW (inAddParity ? AddEvenParity(*iter) : *iter);
469 outUDWs.push_back(UDW);
477 outUDWs.resize(origSize);
485 return m_payload[inIndex0];
493 if (inIndex0 >= GetDC())
496 m_payload[inIndex0] = inDataByte;
504 m_rcvDataValid =
false;
513 const size_t inMaxBytes,
515 uint32_t & outPacketByteCount)
518 outPacketByteCount = 0;
550 const uint32_t maxBytes(uint32_t(inMaxBytes+0));
560 outPacketByteCount = maxBytes;
566 if (pInData[0] != 0xFF)
569 LOGMYDEBUG(
"No data: First GUMP byte is " <<
xHEX0N(uint16_t(pInData[0]),2) <<
", expected 0xFF");
578 if (totalBytes > maxBytes)
580 outPacketByteCount = maxBytes;
581 LOGMYERROR(
"AJA_STATUS_RANGE: Reported packet size " << totalBytes <<
" [bytes] extends past end of buffer " << inMaxBytes <<
" by " << (totalBytes-inMaxBytes) <<
" byte(s)");
589 m_checksum = pInData[totalBytes-1];
592 m_location = inLocationInfo;
594 if ((pInData[1] & 0x80) != 0)
600 m_location.SetLineNumber(uint16_t((pInData[1] & 0x0F) << 7) + uint16_t(pInData[2] & 0x7F));
606 const uint32_t payloadSize (pInData[5]);
609 status = AllocDataMemory(payloadSize);
611 for (uint32_t ndx(0); ndx < payloadSize; ndx++)
612 m_payload[ndx] = pInData[ndx+6];
615 outPacketByteCount = totalBytes;
616 LOGMYDEBUG(
"Set from GUMP buffer OK: " << AsString(32));
624 const size_t inMaxBytes,
625 uint32_t & outPacketByteCount)
650 outPacketByteCount = 0;
657 if (!AuxPacketTypeIsValid(pInData[0]))
660 outPacketByteCount = 0;
661 LOGMYDEBUG(
"No data: First Aux byte " <<
xHEX0N(uint16_t(pInData[0]),2) <<
" is not a recognized type");
665 const uint32_t maxBytes(uint32_t(inMaxBytes+0));
669 outPacketByteCount = maxBytes;
679 m_auxType = pInData[0];
680 m_auxHB1 = pInData[1];
681 m_auxHB2 = pInData[2];
685 uint32_t payloadSize(28);
686 int payloadOffset(3);
687 if (m_auxType & 0x80)
689 m_checksum = pInData[3];
690 payloadSize = m_auxHB2 & 0x0000001F;
700 status = AllocDataMemory(payloadSize);
702 for (uint32_t ndx(0); ndx < payloadSize; ndx++)
703 m_payload[ndx] = pInData[ndx+payloadOffset];
706 outPacketByteCount = totalBytes;
707 LOGMYDEBUG(
"Set from HDMI buffer OK: " << AsString(32));
714 uint32_t pktByteCount(0);
717 return InitWithReceivedData (&inData[0], uint32_t(inData.size()), inLocationInfo, pktByteCount);
738 LOGMYWARN(
"Illegal packet size " <<
DEC(GetDC()) <<
", exceeds 255 -- returning truncated value (255): " << AsString(32));
748 const uint32_t numPackets ((GetDC() + 254) / 255);
749 const uint32_t lastPacketDC (GetDC() % 255);
768 AJAStatus status (GeneratePayloadData());
773 uint32_t myPacketSize(0), maxBytes(uint32_t(inMaxBytes+0));
774 GetRawPacketSize(myPacketSize);
776 if (myPacketSize == 0)
778 LOGMYERROR(
"AJA_STATUS_FAIL: nothing to do -- raw packet size is zero: " << AsString(32));
781 if (myPacketSize > maxBytes)
783 LOGMYERROR(
"AJA_STATUS_FAIL: " << maxBytes <<
"-byte client buffer too small to hold " << myPacketSize <<
" byte(s): " << AsString(32));
786 if (!IsDigital() && !
IsRaw())
788 LOGMYERROR(
"AJA_STATUS_FAIL: invalid packet coding (neither Raw nor Digital): " << AsString(32));
794 pData[0] = GetGUMPHeaderByte1();
795 pData[1] = GetGUMPHeaderByte2();
796 pData[2] = GetGUMPHeaderByte3();
800 uint8_t payloadSize = uint8_t((GetDC() > 255) ? 255 : GetDC());
801 pData[5] = payloadSize;
804 status = GetPayloadData(&pData[6], payloadSize);
808 pData[6+payloadSize] = Calculate8BitChecksum();
811 outPacketSize = myPacketSize;
818 const uint32_t numPackets ((GetDC() + 254) / 255);
823 const uint8_t * payloadPtr = GetPayloadData();
824 uint32_t remainingPayloadData = GetDC();
826 for (uint32_t ndx(0); ndx < numPackets; ndx++)
828 pData[0] = GetGUMPHeaderByte1();
829 pData[1] = GetGUMPHeaderByte2();
830 pData[2] = GetGUMPHeaderByte3();
834 uint8_t payloadSize = uint8_t((remainingPayloadData > 255) ? 255 : remainingPayloadData);
835 pData[5] = payloadSize;
838 ::memcpy(&pData[6], payloadPtr, payloadSize);
842 pData[6+payloadSize] = m_checksum;
845 payloadPtr += payloadSize;
848 remainingPayloadData -= payloadSize;
854 outPacketSize = myPacketSize;
856 LOGMYDEBUG(outPacketSize <<
" byte(s) generated: " << AsString(32));
864 uint8_t result (0x80);
869 if (m_location.IsLumaChannel())
872 if (m_location.IsHanc())
876 result |= (m_location.GetLineNumber() >> 7) & 0x0F;
884 AJAStatus status (GeneratePayloadData());
885 const UWordSequence::size_type origSize (outRawComponents.size());
891 const uint8_t dataCount ((GetDC() > 255) ? 255 : uint8_t(GetDC()));
892 outRawComponents.push_back(0x000);
893 outRawComponents.push_back(0x3FF);
894 outRawComponents.push_back(0x3FF);
895 outRawComponents.push_back(AddEvenParity(GetDID()));
896 outRawComponents.push_back(AddEvenParity(GetSID()));
897 outRawComponents.push_back(AddEvenParity(dataCount));
901 outRawComponents.resize(origSize);
908 status = GetPayloadData(outRawComponents, IsDigital() );
912 outRawComponents.push_back(Calculate9BitChecksum());
915 {
LOGMYDEBUG((origSize ?
"Appended " :
"Generated ") << (outRawComponents.size() - origSize) <<
" UWords from " << AsString(32) << endl <<
UWordSequence(outRawComponents));}
923 static const size_t gIndexes[] = { 0,1,2,3, 3,4,5,6, 6,7,8,9, 9,10,11,12, 12,13,14,15 };
924 static const unsigned gShifts[] = { 22,12,2,8, 24,14,4,6, 26,16,6,4, 28,18,8,2, 30,20,10,0 };
925 static const uint32_t
gMasks[] = { 0xFFC00000, 0x003FF000, 0x00000FFC, 0x00000003,
926 0xFF000000, 0x00FFC000, 0x00003FF0, 0x0000000F,
927 0xFC000000, 0x03FF0000, 0x0000FFC0, 0x0000003F,
928 0xF0000000, 0x0FFC0000, 0x0003FF00, 0x000000FF,
929 0xC0000000, 0x3FF00000, 0x000FFC00, 0x000003FF };
934 AJAStatus status (GeneratePayloadData());
935 const ULWordSequence::size_type origSize (outData.size());
945 const uint16_t did (AddEvenParity(GetDID()));
946 const uint16_t sid (AddEvenParity(GetSID()));
947 const uint16_t dc (AddEvenParity(uint8_t(GetDC())));
948 const uint16_t cs (Calculate9BitChecksum());
951 UDW16s.reserve(GetDC()+4);
952 UDW16s.push_back(did);
953 UDW16s.push_back(sid);
954 UDW16s.push_back(dc);
957 status = GetPayloadData(UDW16s,
true);
959 {
XMT2110ERR(
"GetPayloadData failed: " << AsString(32));
return status;}
960 UDW16s.push_back(cs);
968 const uint32_t pktHdrWord (pktHdr.
GetULWord());
969 outData.push_back(pktHdrWord);
973 const size_t numUDWs (UDW16s.size());
978 for (
unsigned loopNdx(0); loopNdx <
sizeof(
gIndexes) /
sizeof(
size_t); loopNdx++)
980 const bool is4th ((loopNdx & 3) == 3);
981 const size_t ndx (UDWndx +
gIndexes[loopNdx]);
982 const bool isPastEnd (ndx >= numUDWs);
983 const uint32_t UDW (isPastEnd ? 0 : uint32_t(UDW16s[ndx]));
984 const unsigned shift (
gShifts[loopNdx]);
985 const uint32_t mask (
gMasks[loopNdx]);
989 u32 |= (UDW >> shift) & mask;
998 u32 |= (UDW << shift) & mask;
1001 }
while (UDWndx < numUDWs);
1033 oss << (origSize ?
"Appended " :
"Generated ") << (outData.size() - origSize) <<
" U32s:";
1034 for (
size_t ndx(origSize); ndx < outData.size(); ndx++)
1036 oss <<
" BigEndian from " << AsString(32);
1040 XMT2110DBG((origSize ?
"Appended " :
"Generated ")
1041 << (outData.size() - origSize) <<
" 32-bit words from " << AsString(32));
1049 const size_t numU32s (inU32s.size());
1053 if (inOutU32Ndx >= numU32s)
1061 RCV2110DDBG(
"u32=" <<
xHEX0N(
ENDIAN_32NtoH(inU32s.at(inOutU32Ndx)),8) <<
" inU32s[" <<
DEC(inOutU32Ndx) <<
" of " <<
DEC(numU32s) <<
"] AncPktHdr: " << ancPktHeader <<
" -- AncDataLoc: " << dataLoc);
1063 if (++inOutU32Ndx >= numU32s)
1068 result = SetLocationVideoLink(dataLoc.GetDataLink());
1069 if (
AJA_FAILURE(result)) {
RCV2110ERR(
"SetLocationVideoLink failed, dataLoc: " << dataLoc);
return result;}
1071 result = SetLocationDataStream(dataLoc.GetDataStream());
1072 if (
AJA_FAILURE(result)) {
RCV2110ERR(
"SetLocationDataStream failed, dataLoc: " << dataLoc);
return result;}
1074 result = SetLocationDataChannel(dataLoc.GetDataChannel());
1075 if (
AJA_FAILURE(result)) {
RCV2110ERR(
"SetLocationDataChannel failed, dataLoc: " << dataLoc);
return result;}
1077 result = SetLocationHorizOffset(dataLoc.GetHorizontalOffset());
1078 if (
AJA_FAILURE(result)) {
RCV2110ERR(
"SetLocationHorizOffset failed, dataLoc: " << dataLoc);
return result;}
1080 result = SetLocationLineNumber(dataLoc.GetLineNumber());
1081 if (
AJA_FAILURE(result)) {
RCV2110ERR(
"SetLocationLineNumber failed, dataLoc: " << dataLoc);
return result;}
1085 bool gotChecksum (
false);
1086 size_t dataCount (0);
1088 const size_t startU32Ndx (inOutU32Ndx);
1093 for (
unsigned loopNdx(0); loopNdx < 20 && !gotChecksum; loopNdx++)
1095 const bool is4th ((loopNdx & 3) == 3);
1096 const bool is1st ((loopNdx & 3) == 0);
1097 const unsigned shift (
gShifts[loopNdx]);
1098 const uint32_t mask (
gMasks[loopNdx]);
1101 u16 = uint16_t((u32 & mask) << shift);
1104 if (++inOutU32Ndx >= numU32s)
1106 u16s.push_back(u16);
1111 <<
" from " <<
DEC(loopNdx) <<
"(" <<
xHEX0N(inU32s.at(inOutU32Ndx-1),8) <<
" & " <<
xHEX0N(mask,8) <<
") << " <<
DEC(shift));
1119 u16 |= uint16_t((u32 & mask) >> shift);
1123 u16 = uint16_t((u32 & mask) >> shift);
1126 u16s.push_back(u16);
1129 case 1: SetDID(uint8_t(u16));
break;
1130 case 2: SetSID(uint8_t(u16));
break;
1131 case 3: dataCount = size_t(u16 & 0x0FF);
break;
1132 default:
if (u16s.size() == (dataCount + 4))
1133 {gotChecksum =
true;
RCV2110DDBG(
"Got checksum, DC=" <<
xHEX0N(dataCount,2) <<
" CS=" <<
xHEX0N(u16s.back(),3));}
1139 }
while (inOutU32Ndx < numU32s);
1141 if (u16s.size() < 4)
1142 { ostringstream oss;
1143 if (u16s.size() < 1) oss <<
" NoDID";
1145 if (u16s.size() < 2) oss <<
" NoSID";
1147 if (u16s.size() < 3) oss <<
" NoDC";
1148 else oss <<
" DC=" <<
DEC(dataCount);
1149 RCV2110ERR(
"Incomplete/bad packet:" << oss.str() <<
" NoCS" <<
" -- only unpacked " << u16s);
1152 RCV2110DBG(
"Consumed " <<
DEC(inOutU32Ndx - startU32Ndx + 1) <<
" ULWord(s), " << (gotChecksum?
"":
"NoCS, ") <<
"DC=" <<
DEC(dataCount) <<
", unpacked " << u16s);
1153 if (inOutU32Ndx < numU32s)
1157 if (dataCount > (u16s.size()-3))
1159 RCV2110ERR(
"Incomplete/bad packet: " <<
DEC(u16s.size()) <<
" U16s, but missing " <<
DEC(dataCount - (u16s.size()-3))
1160 <<
" byte(s), expected DC=" <<
DEC(dataCount) <<
" -- DID=" <<
xHEX0N(
UWord(GetDID()),2) <<
" SID=" <<
xHEX0N(
UWord(GetSID()),2));
1165 for (
size_t ndx(0); ndx < dataCount; ndx++)
1166 m_payload.push_back(uint8_t(u16s.at(ndx+3)));
1168 result = SetChecksum(uint8_t(u16s.at(u16s.size()-1)),
true );
1171 if (inIgnoreChecksum)
1174 {
RCV2110ERR(
"SetChecksum=" <<
xHEX0N(u16s.at(u16s.size()-1),3) <<
" failed, calculated=" <<
xHEX0N(Calculate9BitChecksum(),3));
return result;}
1235 static const string gAncDataLinkToStr [] = {
"A",
"B",
"?"};
1236 static const string gDAncDataLinkToStr [] = {
"AJAAncDataLink_A",
"AJAAncDataLink_B",
"AJAAncDataLink_Unknown"};
1238 return IS_VALID_AJAAncDataLink(inValue) ? (inCompact ? gAncDataLinkToStr[inValue] : gDAncDataLinkToStr[inValue]) : gAncDataLinkToStr[2];
1244 static const string gAncDataStreamToStr [] = {
"DS1",
"DS2",
"DS3",
"DS4",
"?"};
1245 static const string gDAncDataStreamToStr [] = {
"AJAAncDataStream_1",
"AJAAncDataStream_2",
1246 "AJAAncDataStream_3",
"AJAAncDataStream_4",
"AJAAncDataStream_Unknown"};
1254 static const string gAncDataChannelToStr [] = {
"C",
"Y",
"?"};
1255 static const string gDAncDataChannelToStr [] = {
"AJAAncDataChannel_C",
"AJAAncDataChannel_Y",
"AJAAncDataChannel_Unknown"};
1263 static const string gAncDataSpaceToStr [] = {
"VANC",
"HANC",
"????"};
1264 static const string gDAncDataSpaceToStr [] = {
"AJAAncDataSpace_VANC",
"AJAAncDataSpace_HANC",
"AJAAncDataSpace_Unknown"};
1282 oss <<
"L" <<
DEC(inValue);
1301 oss <<
"+" <<
DEC(inValue);
1352 if (oss.str().length() > 2)
1353 return oss.str().substr(2, oss.str().length() - 2);
1361 inValue.
Print(oss, inCompact);
1367 return inValue.
Print(inOutStream,
true);
1373 static const string gAncDataCodingToStr [] = {
"Dig",
"Ana",
"???"};
1374 static const string gDAncDataCodingToStr [] = {
"AJAAncDataCoding_Digital",
"AJAAncDataCoding_Raw",
"AJAAncDataCoding_Unknown"};
1382 static const string gAncBufFmtToStr [] = {
"UNK",
"FBVANC",
"SDI",
"RTP",
"HDMI",
""};
1383 static const string gDAncBufFmtToStr [] = {
"AJAAncBufferFormat_Unknown",
"AJAAncBufferFormat_FBVANC",
1384 "AJAAncBufferFormat_SDI",
"AJAAncBufferFormat_RTP",
"AJAAncBufferFormat_HDMI",
""};
1392 static const string gAncDataTypeToStr [] = {
"Unknown",
"SMPTE 2016-3 AFD",
"SMPTE 12-M RP188",
"SMPTE 12-M VITC",
1393 "SMPTE 334 CEA708",
"SMPTE 334 CEA608",
"CEA608 Line21",
"SMPTE 352 VPID",
1394 "SMPTE 2051 2 Frame Marker",
"524D Frame Status",
"5251 Frame Status",
1395 "HDR SDR",
"HDR10",
"HDR HLG",
"HDMI Aux",
"?"};
1397 static const string gDAncDataTypeToStr [] = {
"AJAAncDataType_Unknown",
"AJAAncDataType_Smpte2016_3",
"AJAAncDataType_Timecode_ATC",
1398 "AJAAncDataType_Timecode_VITC",
"AJAAncDataType_Cea708",
"AJAAncDataType_Cea608_Vanc",
1399 "AJAAncDataType_Cea608_Line21",
"AJAAncDataType_Smpte352",
"AJAAncDataType_Smpte2051",
1400 "AJAAncDataType_FrameStatusInfo524D",
"AJAAncDataType_FrameStatusInfo5251",
1401 "AJAAncDataType_HDR_SDR",
"AJAAncDataType_HDR_HDR10",
"AJAAncDataType_HDR_HLG",
1402 "AJAAncDataType_HDMI_Aux",
"?"};
1410 oss <<
"Type:\t\t" << IDAsString() << endl;
1412 oss <<
"DID:\t\t" <<
xHEX0N(uint32_t(GetDID()),2) << endl
1413 <<
"SID:\t\t" <<
xHEX0N(uint32_t(GetSID()),2) << endl;
1414 oss <<
"DC:\t\t" <<
DEC(GetDC()) << endl;
1416 oss <<
"CS:\t\t" <<
xHEX0N(uint32_t(m_checksum),2) << endl
1417 <<
"Loc:\t\t" << GetDataLocation() << endl;
1419 <<
"Frame:\t\t" <<
xHEX0N(GetFrameID(),8) << endl
1421 <<
"Valid:\t\t" << (GotValidReceiveData() ?
"Yes" :
"No");
1423 {oss << endl; DumpPayload(oss);}
1431 oss <<
"Analog/Raw Line " <<
DEC(GetDataLocation().GetLineNumber()) <<
" Packet";
1433 oss << AuxPacketTypeToString(GetAuxType());
1435 oss << DIDSIDToString(GetDID(), GetSID());
1444 oss <<
"|" <<
xHEX0N(uint16_t(GetAuxType()),2)
1445 <<
HEX0N(uint16_t(GetAuxHB1()),2)
1446 <<
HEX0N(uint16_t(GetAuxHB2()),2);
1449 <<
"|" << GetDIDSIDPair() <<
"|CS" <<
HEX0N(uint16_t(GetChecksum()),2);
1450 oss <<
"|DC=" <<
DEC(GetDC());
1452 oss <<
"|FRx" <<
HEX0N(GetFrameID(),8);
1455 const string typeStr (IsHDMI() ? AuxPacketTypeToString(GetAuxType())
1456 : DIDSIDToString(GetDID(), GetSID()));
1457 if (!typeStr.empty())
1458 oss <<
"|" << typeStr;
1460 if (inMaxBytes && GetDC())
1462 uint16_t bytesToDump = uint16_t(GetDC());
1464 if (inMaxBytes < bytesToDump)
1465 bytesToDump = inMaxBytes;
1466 for (uint16_t ndx(0); ndx < bytesToDump; ndx++)
1467 oss <<
HEX0N(uint16_t(m_payload[ndx]),2);
1468 if (bytesToDump < uint16_t(GetDC()))
1476 inOutStream <<
"x" <<
HEX0N(uint16_t(inData.first), 2) <<
"x" <<
HEX0N(uint16_t(inData.second), 2);
1483 inOutStream <<
"(NULL payload)" << endl;
1486 const int32_t kBytesPerLine (32);
1487 uint32_t count (GetDC());
1488 const uint8_t * pData (GetPayloadData());
1492 const uint32_t numBytes ((count >= kBytesPerLine) ? kBytesPerLine : count);
1493 inOutStream << ((count == GetDC()) ?
"Payload: " :
" ");
1494 for (uint8_t num(0); num < numBytes; num++)
1496 inOutStream <<
" " <<
HEX0N(uint32_t(pData[num]),2);
1500 inOutStream << endl;
1511 if (GetDID() != inRHS.
GetDID())
1513 if (GetSID() != inRHS.
GetSID())
1515 if (GetDC() != inRHS.
GetDC())
1518 if (!inIgnoreChecksum)
1521 if (!inIgnoreLocation)
1539 if (GetDID() != inRHS.
GetDID())
1540 oss << endl <<
"DID mismatch: " <<
xHEX0N(uint16_t(GetDID()),2) <<
" != " <<
xHEX0N(uint16_t(inRHS.
GetDID()),2);
1541 if (GetSID() != inRHS.
GetSID())
1542 oss << endl <<
"SID mismatch: " <<
xHEX0N(uint16_t(GetSID()),2) <<
" != " <<
xHEX0N(uint16_t(inRHS.
GetSID()),2);
1543 if (GetDC() != inRHS.
GetDC())
1544 oss << endl <<
"DC mismatch: " <<
xHEX0N(GetDC(),4) <<
" != " <<
xHEX0N(inRHS.
GetDC(),4);
1546 if (!inIgnoreChecksum)
1548 oss << endl <<
"CS mismatch: " <<
xHEX0N(uint16_t(GetChecksum()),2) <<
" != " <<
xHEX0N(uint16_t(inRHS.
GetChecksum()),2);
1549 if (!inIgnoreLocation)
1550 {
const string info(GetDataLocation().CompareWithInfo(inRHS.
GetDataLocation()));
1552 oss << endl <<
"Location mismatch: " << info;
1560 const uint8_t *pLHS(GetPayloadData()), *pRHS(inRHS.
GetPayloadData());
1562 for (
size_t ndx(0); ndx < GetPayloadByteCount(); ndx++)
1563 if (pLHS[ndx] != pRHS[ndx])
1564 diffNdxs.push_back(
ULWord(ndx));
1565 if (!diffNdxs.empty())
1566 oss << endl <<
DEC(diffNdxs.size()) <<
" of " <<
DEC(GetDC()) <<
" (" <<
fDEC(100.0*
double(diffNdxs.size())/
double(GetDC()), 5, 2)
1567 <<
"%) mismatched payload bytes, starting at offset " <<
DEC(diffNdxs.at(0));
1570 if (oss.str().length() >
sENDL)
1571 return oss.str().substr(
sENDL, oss.str().length() -
sENDL);
1579 m_DID = inRHS.
m_DID;
1580 m_SID = inRHS.
m_SID;
1609 static const uint16_t gEvenParityTable[256] =
1611 0x200,0x101,0x102,0x203,0x104,0x205,0x206,0x107,
1612 0x108,0x209,0x20A,0x10B,0x20C,0x10D,0x10E,0x20F,
1613 0x110,0x211,0x212,0x113,0x214,0x115,0x116,0x217,
1614 0x218,0x119,0x11A,0x21B,0x11C,0x21D,0x21E,0x11F,
1615 0x120,0x221,0x222,0x123,0x224,0x125,0x126,0x227,
1616 0x228,0x129,0x12A,0x22B,0x12C,0x22D,0x22E,0x12F,
1617 0x230,0x131,0x132,0x233,0x134,0x235,0x236,0x137,
1618 0x138,0x239,0x23A,0x13B,0x23C,0x13D,0x13E,0x23F,
1619 0x140,0x241,0x242,0x143,0x244,0x145,0x146,0x247,
1620 0x248,0x149,0x14A,0x24B,0x14C,0x24D,0x24E,0x14F,
1621 0x250,0x151,0x152,0x253,0x154,0x255,0x256,0x157,
1622 0x158,0x259,0x25A,0x15B,0x25C,0x15D,0x15E,0x25F,
1623 0x260,0x161,0x162,0x263,0x164,0x265,0x266,0x167,
1624 0x168,0x269,0x26A,0x16B,0x26C,0x16D,0x16E,0x26F,
1625 0x170,0x271,0x272,0x173,0x274,0x175,0x176,0x277,
1626 0x278,0x179,0x17A,0x27B,0x17C,0x27D,0x27E,0x17F,
1627 0x180,0x281,0x282,0x183,0x284,0x185,0x186,0x287,
1628 0x288,0x189,0x18A,0x28B,0x18C,0x28D,0x28E,0x18F,
1629 0x290,0x191,0x192,0x293,0x194,0x295,0x296,0x197,
1630 0x198,0x299,0x29A,0x19B,0x29C,0x19D,0x19E,0x29F,
1631 0x2A0,0x1A1,0x1A2,0x2A3,0x1A4,0x2A5,0x2A6,0x1A7,
1632 0x1A8,0x2A9,0x2AA,0x1AB,0x2AC,0x1AD,0x1AE,0x2AF,
1633 0x1B0,0x2B1,0x2B2,0x1B3,0x2B4,0x1B5,0x1B6,0x2B7,
1634 0x2B8,0x1B9,0x1BA,0x2BB,0x1BC,0x2BD,0x2BE,0x1BF,
1635 0x2C0,0x1C1,0x1C2,0x2C3,0x1C4,0x2C5,0x2C6,0x1C7,
1636 0x1C8,0x2C9,0x2CA,0x1CB,0x2CC,0x1CD,0x1CE,0x2CF,
1637 0x1D0,0x2D1,0x2D2,0x1D3,0x2D4,0x1D5,0x1D6,0x2D7,
1638 0x2D8,0x1D9,0x1DA,0x2DB,0x1DC,0x2DD,0x2DE,0x1DF,
1639 0x1E0,0x2E1,0x2E2,0x1E3,0x2E4,0x1E5,0x1E6,0x2E7,
1640 0x2E8,0x1E9,0x1EA,0x2EB,0x1EC,0x2ED,0x2EE,0x1EF,
1641 0x2F0,0x1F1,0x1F2,0x2F3,0x1F4,0x2F5,0x2F6,0x1F7,
1642 0x1F8,0x2F9,0x2FA,0x1FB,0x2FC,0x1FD,0x1FE,0x2FF
1644 return gEvenParityTable[inDataByte];
1662 const uint16_t inStartIndex,
1663 const uint16_t inTotalCount,
1664 const uint16_t inIncrement = 2)
1668 if (inIncrement == 0 || inIncrement > 2)
1672 for (ndx = 3; ndx < inTotalCount - 1; ndx++)
1674 const UWord wordValue (inYUV16Line[inStartIndex + ndx * inIncrement]);
1677 LOGMYERROR (
"Parity error at word " << ndx <<
": got " <<
xHEX0N(wordValue,2)
1684 const UWord checksum (inYUV16Line [inStartIndex + (inTotalCount - 1) * inIncrement]);
1685 const bool b8 ((checksum &
BIT(8)) != 0);
1686 const bool b9 ((checksum &
BIT(9)) != 0);
1689 LOGMYERROR (
"Checksum word error: got " <<
xHEX0N(checksum,2) <<
", expected " <<
xHEX0N(checksum ^ 0x200, 2));
1695 for (ndx = 3; ndx < inTotalCount - 1; ndx++)
1696 sum += inYUV16Line [inStartIndex + ndx * inIncrement] & 0x1FF;
1698 if ((sum & 0x1FF) != (checksum & 0x1FF))
1700 LOGMYERROR (
"Checksum math error: got " <<
xHEX0N(checksum & 0x1FF, 2) <<
", expected " <<
xHEX0N(sum & 0x1FF, 2));
1714 const UWord wordCountMax (
UWord(inYUV16Line.size ()));
1722 outRawPackets.clear();
1723 outWordOffsets.clear();
1726 {
LOGMYERROR(
"Bad search select value " <<
DEC(inChanSelect));
return false;}
1727 if (wordCountMax < 12)
1728 {
LOGMYERROR(
"UWordSequence size " <<
DEC(wordCountMax) <<
" too small");
return false;}
1730 for (
UWord wordNum = searchOffset; wordNum < (wordCountMax - 12); wordNum += searchIncr)
1732 const UWord ancHdr0 (inYUV16Line.at (wordNum + (0 * searchIncr)));
1733 const UWord ancHdr1 (inYUV16Line.at (wordNum + (1 * searchIncr)));
1734 const UWord ancHdr2 (inYUV16Line.at (wordNum + (2 * searchIncr)));
1735 const UWord ancHdr3 (inYUV16Line.at (wordNum + (3 * searchIncr)));
1736 const UWord ancHdr4 (inYUV16Line.at (wordNum + (4 * searchIncr)));
1737 const UWord ancHdr5 (inYUV16Line.at (wordNum + (5 * searchIncr)));
1738 if (ancHdr0 == 0x000 && ancHdr1 == 0x3ff && ancHdr2 == 0x3ff)
1741 UWord dataCount (ancHdr5 & 0xFF);
1742 UWord totalCount (6 + dataCount + 1);
1744 if (totalCount > wordCountMax)
1746 totalCount = wordCountMax;
1747 LOGMYERROR (
"packet totalCount " << totalCount <<
" exceeds max " << wordCountMax);
1752 if (
ULWord (wordNum + totalCount) >= wordCountMax)
1754 LOGMYDEBUG (
"past end of line: " << wordNum <<
" + " << totalCount <<
" >= " << wordCountMax);
1762 for (
unsigned i = 0; i < totalCount; i++)
1763 packet.push_back (inYUV16Line.at (wordNum + (i * searchIncr)));
1764 outRawPackets.push_back (packet);
1765 outWordOffsets.push_back (wordNum);
1768 <<
": DID=" <<
xHEX0N(ancHdr3,4)
1769 <<
" SDID=" <<
xHEX0N(ancHdr4,4)
1770 <<
" word=" << wordNum
1771 <<
" DC=" << ancHdr5
1772 <<
" pix=" << (wordNum / searchIncr));
1783 const uint32_t inNumPixels)
1785 const UByte * pInYUV8Buffer (reinterpret_cast <const UByte *> (pInYUV8Line));
1786 const ULWord maxOutElements (inNumPixels * 2);
1788 outU16YUVLine.clear ();
1789 outU16YUVLine.reserve (maxOutElements);
1790 while (outU16YUVLine.size() < size_t(maxOutElements))
1791 outU16YUVLine.push_back(0);
1794 {
LOGMYERROR(
"NULL/empty YUV8 buffer");
return false;}
1795 if (inNumPixels < 12)
1796 {
LOGMYERROR(
"width in pixels " <<
DEC(inNumPixels) <<
" too small (< 12)");
return false;}
1797 if (inNumPixels % 4)
1798 {
LOGMYERROR(
"width in pixels " <<
DEC(inNumPixels) <<
" not multiple of 4");
return false;}
1802 for (
ULWord comp = 0; comp < 2; comp++)
1804 bool bNoMoreAnc (
false);
1814 while (pixNum < inNumPixels)
1819 const ULWord index (2 * pixNum + comp);
1823 if (index <
ULWord(outU16YUVLine.size()))
1824 outU16YUVLine[index] = dataValue;
1826 outU16YUVLine.push_back(dataValue);
1833 if ((pixNum + 7) < inNumPixels)
1835 if ( pInYUV8Buffer [2*(pixNum+0) + comp] == 0x00
1836 && pInYUV8Buffer [2*(pixNum+1) + comp] == 0xFF
1837 && pInYUV8Buffer [2*(pixNum+2) + comp] == 0xFF)
1840 outU16YUVLine [2*pixNum++ + comp] = 0x000;
1841 outU16YUVLine [2*pixNum++ + comp] = 0x3ff;
1842 outU16YUVLine [2*pixNum++ + comp] = 0x3ff;
1844 ancCount = pInYUV8Buffer[2*(pixNum+2) + comp] + 3 + 1;
1853 else if (ancCount == 1)
1856 outU16YUVLine [2*pixNum + comp] = checksum & 0x1ff;
1857 outU16YUVLine [2*pixNum + comp] |= (~checksum & 0x100) << 1;
1865 const UByte ancByte (pInYUV8Buffer [2*pixNum + comp]);
1866 const UWord ancWord (AddEvenParity (ancByte));
1868 outU16YUVLine [2*pixNum + comp] = ancWord;
1870 checksum += (ancWord & 0x1ff);
1885 const uint32_t inNumPixels)
1887 const UByte * pInYUV8Buffer (reinterpret_cast<const UByte*>(pInYUV8Line));
1888 const ULWord maxNumElements(inNumPixels * 2);
1890 outU16YUVLine.clear ();
1891 outU16YUVLine.reserve (maxNumElements);
1892 while (outU16YUVLine.size() < size_t(maxNumElements))
1893 outU16YUVLine.push_back(0);
1896 {
LOGMYERROR(
"NULL/empty YUV8 buffer");
return false;}
1897 if (inNumPixels < 12)
1898 {
LOGMYERROR(
"width in pixels " <<
DEC(inNumPixels) <<
" too small (< 12)");
return false;}
1899 if (inNumPixels % 4)
1900 {
LOGMYERROR(
"width in pixels " <<
DEC(inNumPixels) <<
" not multiple of 4");
return false;}
1903 bool bNoMoreAnc(
false);
1912 while (ndx < maxNumElements)
1920 if (ndx <
ULWord(outU16YUVLine.size()))
1921 outU16YUVLine[ndx] = dataValue;
1923 outU16YUVLine.push_back(dataValue);
1930 if ((ndx + 7) < maxNumElements)
1932 if ( pInYUV8Buffer [ndx+0] == 0x00
1933 && pInYUV8Buffer [ndx+1] == 0xFF
1934 && pInYUV8Buffer [ndx+2] == 0xFF)
1937 outU16YUVLine [ndx++] = 0x000;
1938 outU16YUVLine [ndx++] = 0x3ff;
1939 outU16YUVLine [ndx++] = 0x3ff;
1940 ancCount = pInYUV8Buffer[ndx+2] + 3 + 1;
1949 else if (ancCount == 1)
1952 outU16YUVLine[ndx] = checksum & 0x1ff;
1953 outU16YUVLine[ndx] |= (~checksum & 0x100) << 1;
1960 const UByte ancByte (pInYUV8Buffer[ndx]);
1961 const UWord ancWord (AddEvenParity(ancByte));
1962 outU16YUVLine[ndx] = ancWord;
1963 checksum += (ancWord & 0x1ff);
1979 outConstructed = outDestructed = 0;
2051 for (uint8_t sid(1); sid < 0x0A; sid++)
2061 for (uint8_t sid(0xD0); sid < 0xE0; sid++)
2131 return didIt->second;
2135 static const NTV2DIDSet sValidHDMIAuxPacketTypes = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
2136 0x80, 0x81, 0x82, 0x83, 0x84, 0x85};
2140 switch (auxPacketType)
2142 case 0x01:
return "Audio Clock Regeneration (N/CTS)";
2143 case 0x02:
return "Audio Sample (L-PCM & IEC-61937 compressed)";
2144 case 0x03:
return "General Control";
2145 case 0x04:
return "ACP Packet";
2146 case 0x05:
return "ISRC1 Packet";
2147 case 0x06:
return "ISRC2 Packet";
2148 case 0x07:
return "One Bit Audio Sample Packet";
2149 case 0x08:
return "DST Audio Packet";
2150 case 0x09:
return "High Bitrate Audio Stream Packet (IEC-61937)";
2151 case 0x0A:
return "Gamut Metadata Packet";
2152 case 0x80:
return "General InfoFrame Packet";
2153 case 0x81:
return "Vendor-Specific InfoFrame";
2154 case 0x82:
return "AVI InfoFrame";
2155 case 0x83:
return "Source Product Descriptor InfoFrame";
2156 case 0x84:
return "Audio InfoFrame";
2157 case 0x85:
return "MPEG Source InfoFrame";
2189 mSequenceNumber (0),
2204 uint32_t u32(uint32_t(mVBits << 30));
2205 u32 |= uint32_t(mPBit ? 1 : 0) << 29;
2206 u32 |= uint32_t(mPBit ? 1 : 0) << 29;
2207 u32 |= uint32_t(mXBit ? 1 : 0) << 28;
2208 u32 |= uint32_t(mCCBits & 0x0000000F) << 24;
2251 case 0: mVBits = uint8_t(u32 >> 30);
2252 mPBit = (u32 & 0x20000000) ?
true :
false;
2253 mXBit = (u32 & 0x10000000) ?
true :
false;
2254 mCCBits = uint8_t((u32 & 0x0F000000) >> 24);
2255 mMarkerBit = (u32 & 0x00800000) ?
true :
false;
2256 mPayloadType = uint8_t((u32 & 0x007F0000) >> 16);
2257 mSequenceNumber = (mSequenceNumber & 0xFFFF0000) | (u32 & 0x0000FFFF);
2260 case 1: mTimeStamp = u32;
2263 case 2: mSyncSourceID = u32;
2266 case 3: mSequenceNumber = (u32 & 0xFFFF0000) | (mSequenceNumber & 0x0000FFFF);
2267 mPayloadLength = uint16_t(u32 & 0x0000FFFF);
2270 case 4: mAncCount = uint8_t((u32 & 0xFF000000) >> 24);
2271 mFieldSignal = uint8_t((u32 & 0x00C00000) >> 22);
2274 default:
return false;
2283 while (outVector.size() < 5)
2284 outVector.push_back(0);
2285 for (
unsigned ndx(0); ndx < 5; ndx++)
2292 const ULWord startingByteOffset (inU32Offset *
sizeof(uint32_t));
2295 uint32_t * pU32s (reinterpret_cast<uint32_t*>(outBuffer.
GetHostAddress(startingByteOffset)));
2296 for (
unsigned ndx(0); ndx < 5; ndx++)
2304 if (inVector.size() < 5)
2306 for (
unsigned ndx(0); ndx < 5; ndx++)
2316 const uint32_t * pU32s (reinterpret_cast <const uint32_t *> (inBuffer.
GetHostPointer()));
2317 for (
unsigned ndx(0); ndx < 5; ndx++)
2325 static const string sStrs[] = {
"p/noF",
"BAD",
"i/F1",
"i/F2" };
2326 return sStrs[inFBits & 0x03];
2331 return mVBits == inRHS.mVBits
2332 && mPBit == inRHS.mPBit
2333 && mXBit == inRHS.mXBit
2334 && mCCBits == inRHS.mCCBits
2335 && mMarkerBit == inRHS.mMarkerBit
2336 && mPayloadType == inRHS.mPayloadType
2337 && mSequenceNumber == inRHS.mSequenceNumber
2338 && mTimeStamp == inRHS.mTimeStamp
2339 && mSyncSourceID == inRHS.mSyncSourceID
2340 && mPayloadLength == inRHS.mPayloadLength
2341 && mAncCount == inRHS.mAncCount
2342 && mFieldSignal == inRHS.mFieldSignal;
2348 inOutStream <<
xHEX0N(word0,8)
2350 <<
": V=" <<
DEC(uint16_t(mVBits))
2351 <<
" P=" << mPBit <<
" X=" << mXBit <<
" CC=" <<
DEC(uint16_t(mCCBits))
2356 << (
IsValid() ?
"" :
" (invalid)");
2362 return !(mVBits || mPBit || mXBit || mCCBits || mMarkerBit || mPayloadType || mSequenceNumber || mTimeStamp || mSyncSourceID || mPayloadLength || mAncCount || mFieldSignal);
2367 return mVBits == 0x02
2406 u32 |= (
IsCBitSet() ? 0x80000000 : 0x00000000);
2408 u32 |=
IsSBitSet() ? 0x00000080 : 0x00000000;
2421 if (u32 & 0x80000000)
2442 if (inIndex0 >= inVector.size())
2483 mStreamNum = uint8_t(lnk);
2485 mStreamNum = uint8_t(ds);
#define AJAAncDataHorizOffset_Unknown
Unknown.
#define IS_LINKB_AJAAncDataStream(_x_)
#define RCV2110DBG(__x__)
static bool AuxPacketTypeIsValid(const uint8_t inAuxPktType)
#define AJA_ENDIAN_32NtoH(__val__)
virtual const uint8_t * GetPayloadData(void) const
virtual uint8_t GetDID(void) const
const string & AJAAncDataSpaceToString(const AJAAncDataSpace inValue, const bool inCompact)
#define AJA_SUCCESS(_status_)
ostream & operator<<(ostream &inOutStream, const AJAAncDataLoc &inValue)
Declares the AJALock class.
virtual AJAStatus GenerateTransmitData(uint8_t *pBuffer, const size_t inMaxBytes, uint32_t &outPacketSize)
Generates "raw" ancillary data from my internal ancillary data (playback) – see SDI Anc Buffer Data ...
AJAAncillaryData & operator=(const AJAAncillaryData &inRHS)
#define RCV2110WARN(__x__)
static bool CheckAncParityAndChecksum(const AJAAncillaryData::U16Packet &inYUV16Line, const uint16_t inStartIndex, const uint16_t inTotalCount, const uint16_t inIncrement=2)
virtual AJAStatus GetRawPacketSize(uint32_t &outPacketSize) const
Returns the number of "raw" ancillary data bytes that will be generated by AJAAncillaryData::Generate...
virtual AJAStatus Compare(const AJAAncDataLoc &inRHS) const
Compares me with another location.
virtual AJAAncillaryData * Clone(void) const
virtual uint8_t GetSID(void) const
virtual AJAStatus SetSID(const uint8_t inSID)
Sets my Secondary Data ID (SID) - (aka the Data Block Number (DBN) for "Type 1" SMPTE-291 packets)...
AJAAncDataLoc & SetHorizontalOffset(uint16_t inHOffset)
Specifies the horizontal packet position in the raster.
AJAAncDataChannel
Identifies which component of a video stream in which the ancillary data is placed or found...
static uint32_t gConstructCount(0)
virtual std::string CompareWithInfo(const AJAAncillaryData &inRHS, const bool inIgnoreLocation=true, const bool inIgnoreChecksum=true) const
Compares me with another packet and returns a string that describes what's different.
virtual AJAStatus SetDID(const uint8_t inDataID)
Sets my Data ID (DID).
#define AJAAncDataLineNumber_Unknown
Packet line number is unknown.
UWordSequence U16Packet
An ordered sequence of 10-bit packet words stored in uint16_t values.
Ancillary data found between SAV and EAV (.
Declares the AJADebug class.
static AJALock sDIDToStringLock
AJAAncDataSpace
Identified the raster section of a video stream that contains the ancillary data. Deprecated in favor...
virtual AJAStatus SetLocationHorizOffset(const uint16_t inOffset)
Sets my ancillary data "location" horizontal offset.
AJAAncDataType m_ancType
One of a known set of ancillary data types (or "Custom" if not identified)
static const size_t gIndexes[]
Only look in luma samples.
Unknown or "don't care".
#define AJA_FAILURE(_status_)
virtual const AJAAncDataLoc & GetDataLocation(void) const
AJAAncDataType
Identifies the ancillary data types that are known to this module.
const uint32_t AJAAuxillaryPacketSize
std::ostream & Print(std::ostream &ostrm, const bool inCompact=true) const
Writes a human-readable rendition of me into the given output stream.
DIDToStringMap::const_iterator DIDToStringMapCI
#define IS_VALID_AncChannelSearchSelect(_x_)
ULWord GetByteCount(void) const
#define IS_VALID_AJAAncDataLink(_x_)
static const unsigned gShifts[]
AJAAncDataStream GetDataStream(void) const
The ancillary data is in the form of a digitized waveform (e.g. CEA-608 captions, VITC...
#define LOGMYERROR(__x__)
virtual std::string AsString(const uint16_t inDumpMaxBytes=0) const
static DIDSIDToStringMap sDIDSIDToStringMap
virtual uint16_t Calculate9BitChecksum(void) const
Generates the official SMPTE 291 9-bit checksum from the DID + SID + DC + payload data...
uint8_t m_auxType
HDMI Aux Header Byte 0 (Packet Type)
virtual AJAStatus InitAuxWithReceivedData(const uint8_t *pInData, const size_t inMaxBytes, uint32_t &outPacketByteCount)
Initializes me from "raw" ancillary data received from hardware (ingest) – see SDI Anc Buffer Data F...
const string & AJAAncDataChannelToString(const AJAAncDataChannel inValue, const bool inCompact)
virtual void Clear(void)
Frees my allocated memory, if any, and resets my members to their default values. ...
map< uint8_t, string > DIDToStringMap
virtual ~AJAAncillaryData()
My destructor.
string AJAAncDataLocToString(const AJAAncDataLoc &inValue, const bool inCompact)
AJAAncDataLoc & SetDataLink(const AJAAncDataLink inLink)
Sets my data link value to the given value (if valid).
uint8_t m_checksum
My 8-bit checksum: DID + SID + DC + payload (w/o parity) [note: NOT the same as the 9-bit checksum in...
static uint32_t ENDIAN_32NtoH(const uint32_t inValue)
#define AJAAncDataHorizOffset_AnyVanc
VANC – Packet placed/found in any legal area of raster line after SAV, but before EAV...
Ancillary data found between EAV and SAV (.
ByteVector m_payload
My payload data (DC = size)
AJAAncDataCoding m_coding
Analog or digital data.
uint16_t GetLineNumber(void) const
#define AJAAncDataLineNumber_Anywhere
static uint32_t ENDIAN_32HtoN(const uint32_t inValue)
uint8_t m_auxHB1
HDMI Aux Header Byte 1 (Header Data)
#define AJAAncDataLineNumber_Future
Line number exceeds 11 bits (future).
virtual AJAStatus SetLocationLineNumber(const uint16_t inLineNum)
Sets my ancillary data "location" frame line number.
pair< AJAAncDIDSIDPair, string > DIDSIDToStringPair
#define NTV2_ASSERT(_expr_)
Defines where the ancillary data can be found within a video stream.
#define IS_VALID_AJAAncDataCoding(_x_)
AJAStatus FreeDataMemory(void)
string AncChannelSearchSelectToString(const AncChannelSearchSelect inSelect, const bool inCompact)
std::vector< uint8_t > ByteVector
const string & AJAAncDataLinkToString(const AJAAncDataLink inValue, const bool inCompact)
uint64_t m_userData
User data (for client use)
virtual std::ostream & Print(std::ostream &inOutStream, const bool inDetailed=false) const
Streams a human-readable representation of me to the given output stream.
const string & AJAAncDataStreamToString(const AJAAncDataStream inValue, const bool inCompact)
std::vector< U16Packet > U16Packets
An ordered sequence of zero or more U16Packet values.
Includes data that is valid, but we don't recognize.
virtual uint8_t GetGUMPHeaderByte2(void) const
ByteVector::const_iterator ByteVectorConstIter
#define AJAAncDataHorizOffset_Anywhere
Unspecified – Packet placed/found in any legal area of raster line.
uint8_t m_auxHB2
HDMI Aux Header Byte 2 (Header Data)
virtual AJAStatus SetLocationDataStream(const AJAAncDataStream inStream)
Sets my ancillary data "location" data stream value (DS1,DS2...).
AJAAncDataChannel GetDataChannel(void) const
virtual AJAStatus SetLocationVideoLink(const AJAAncDataLink inLink)
Sets my ancillary data "location" within the video stream.
const string & AJAAncBufferFormatToString(const AJAAncBufferFormat inValue, const bool inCompact)
static const uint32_t gMasks[]
const string & AJAAncDataCodingToString(const AJAAncDataCoding inValue, const bool inCompact)
AJAAncDataLoc & SetLineNumber(const uint16_t inLineNum)
Sets my anc data line number value.
virtual AJAStatus AppendPayload(const AJAAncillaryData &inAncData)
Appends payload data from another AJAAncillaryData object to my existing payload. ...
The ancillary data is associated with the chrominance (C) channel of the video stream.
#define IS_KNOWN_AJAAncBufferFormat(_x_)
const uint32_t AJAAncillaryDataWrapperSize
The ancillary data is associated with the luminance (Y) channel of the video stream.
virtual uint8_t Calculate8BitChecksum(void) const
Generates an 8-bit checksum from the DID + SID + DC + payload data.
virtual AJAStatus ParsePayloadData(void)
Parses (interprets) the "local" ancillary data from my payload data.
static std::string AuxPacketTypeToString(const uint8_t inAuxPktType)
std::vector< uint16_t > UWordSequence
An ordered sequence of UWord (uint16_t) values.
AJAAncDataLink GetDataLink(void) const
virtual AJAStatus SetDataCoding(const AJAAncDataCoding inCodingType)
Sets my ancillary data coding type (e.g. digital or analog/raw waveform).
virtual size_t GetPayloadByteCount(void) const
static uint32_t GetNumDestructed(void)
static int32_t Increment(int32_t volatile *pTarget)
virtual AJAStatus InitWithReceivedData(const uint8_t *pInData, const size_t inMaxBytes, const AJAAncDataLoc &inLocationInfo, uint32_t &outPacketByteCount)
Initializes me from "raw" ancillary data received from hardware (ingest) – see SDI Anc Buffer Data F...
AJAAncDataLoc & SetDataStream(const AJAAncDataStream inStream)
Sets my data link value to the given value (if valid).
virtual AJAStatus SetChecksum(const uint8_t inChecksum8, const bool inValidate=false)
Sets my 8-bit checksum. Note that it is not usually necessary to generate an 8-bit checksum...
static bool GetAncPacketsFromVANCLine(const UWordSequence &inYUV16Line, const AncChannelSearchSelect inChanSelect, U16Packets &outRawPackets, U16Packet &outWordOffsets)
Extracts whatever VANC packets are found inside the given 16-bit YUV line buffer. ...
virtual AJAStatus SetDataLocation(const AJAAncDataLoc &inLoc)
Sets my ancillary data "location" within the video stream.
Describes a user-space buffer on the host computer. I have an address and a length, plus some optional attributes (allocated by SDK?, page-aligned? etc.).
AJAAncDataStream
Identifies which data stream the ancillary data is associated with.
virtual AJAStatus AppendPayloadData(const uint8_t *pInBuffer, const uint32_t inByteCount)
Appends data from an external buffer onto the end of my existing payload.
Declares the AJAAtomic class.
static bool Unpack8BitYCbCrToU16sVANCLineSD(const void *pInYUV8Line, UWordSequence &outU16YUVLine, const uint32_t inNumPixels)
SD version of Unpack8BitYCbCrToU16sVANCLine.
const string & AJAAncDataTypeToString(const AJAAncDataType inValue, const bool inCompact)
AncChannelSearchSelect
Specifies which channel of a video stream in which to look for Anc data.
static void ResetInstanceCounts(void)
AJAAncDataLoc & SetDataChannel(const AJAAncDataChannel inChannel)
Sets my data video stream value to the given value (if valid).
#define XMT2110WARN(__x__)
AJAAncillaryData()
My default constructor.
virtual AJAStatus SetPayloadByteAtIndex(const uint8_t inDataByte, const uint32_t inIndex0)
virtual uint8_t GetPayloadByteAtIndex(const uint32_t inIndex0) const
static void GetInstanceCounts(uint32_t &outConstructed, uint32_t &outDestructed)
uint8_t m_SID
Official SMPTE secondary ID (or DBN - w/o parity)
std::pair< uint8_t, uint8_t > AJAAncDIDSIDPair
static std::string DIDSIDToString(const uint8_t inDID, const uint8_t inSDID)
#define IS_VALID_AJAAncDataStream(_x_)
#define AJAAncDataHorizOffset_AnyHanc
HANC – Packet placed/found in any legal area of raster line after EAV.
The ancillary data is associated with Link A of the video stream.
#define LOGMYDEBUG(__x__)
bool IsRaw(const NTV2FrameBufferFormat format)
#define XMT2110DBG(__x__)
static bool Unpack8BitYCbCrToU16sVANCLine(const void *pInYUV8Line, U16Packet &outU16YUVLine, const uint32_t inNumPixels)
Converts a single line of NTV2_FBF_8BIT_YCBCR data from the given source buffer into an ordered seque...
Look both luma and chroma samples (SD only)
uint32_t m_frameID
ID of my originating frame, if known.
ByteVector::size_type ByteVectorIndex
virtual AJAAncDataCoding GetDataCoding(void) const
virtual AJAStatus SetPayloadData(const uint8_t *pInData, const uint32_t inByteCount)
Copy data from external memory into my local payload memory.
virtual std::ostream & DumpPayload(std::ostream &inOutStream) const
Dumps a human-readable representation of my payload bytes into the given output stream.
virtual uint16_t GetStreamInfo(void) const
#define xHEX0N(__x__, __n__)
#define IS_VALID_AJAAncDataChannel(_x_)
Declares the AJAAncillaryData class.
virtual AJAStatus SetLocationDataChannel(const AJAAncDataChannel inChannel)
Sets my ancillary data "location" data channel value (Y or C).
AJAAncDataCoding
Identifies the ancillary data coding type: digital or non-digital (analog/raw).
pair< uint8_t, string > DIDToStringPair
#define XMT2110ERR(__x__)
AJAAncDataLink
Identifies which link of a video stream the ancillary data is associated with.
DIDSIDToStringMap::const_iterator DIDSIDToStringMapCI
#define fDEC(__x__, __w__, __p__)
std::string AJAStatusToString(const AJAStatus inStatus, const bool inDetailed)
uint8_t m_DID
Official SMPTE ancillary packet ID (w/o parity)
std::vector< uint32_t > ULWordSequence
An ordered sequence of ULWord (uint32_t) values.
AJAAncDataLoc m_location
Location of the ancillary data in the video stream (Y or C, HANC or VANC, etc.)
string AJAAncHorizOffsetToString(const uint16_t inValue)
virtual uint8_t GetChecksum(void) const
virtual uint32_t GetDC(void) const
static uint32_t GetNumActiveInstances(void)
void * GetHostPointer(void) const
string AJAAncLineNumberToString(const uint16_t inValue)
#define IS_VALID_AJAAncBufferFormat(_x_)
static uint32_t GetNumConstructed(void)
virtual std::string IDAsString(void) const
#define HEX0N(__x__, __n__)
I am the principal class that stores a single SMPTE-291 SDI ancillary data packet OR the digitized co...
map< AJAAncDIDSIDPair, string > DIDSIDToStringMap
bool m_rcvDataValid
This is set true (or not) by ParsePayloadData()
uint16_t GetHorizontalOffset(void) const
#define AJAAncDataLineNumber_AnyVanc
Packet placed/found on any line past RP168 switch line and before SAV.
#define RCV2110ERR(__x__)
virtual AJAStatus Compare(const AJAAncillaryData &inRHS, const bool inIgnoreLocation=true, const bool inIgnoreChecksum=true) const
Compares me with another packet.
void * GetHostAddress(const ULWord inByteOffset, const bool inFromEnd=false) const
static const NTV2DIDSet sValidHDMIAuxPacketTypes
virtual bool operator==(const AJAAncillaryData &inRHS) const
Declares enums and structs used by all platform drivers and the SDK.
#define AJAAncDataHorizOffset_Future
Offset exceeds 12 bits (future).
Only look in chroma samples.
virtual std::string CompareWithInfo(const AJAAncDataLoc &inRHS) const
Compares me with another location and returns a string that describes what's different.
AJAAncBufferFormat m_bufferFmt
My originating buffer format, if known.
static uint16_t AddEvenParity(const uint8_t inDataByte)
The ancillary data is associated with Link B of the video stream.
static DIDToStringMap sDIDToStringMap
AJAStatus AllocDataMemory(const uint32_t inNumBytes)
#define IS_VALID_AJAAncDataSpace(_x_)
The ancillary data is associated with DS1 of the video stream (Link A).
virtual AJAStatus SetFromSMPTE334(const uint16_t *pInData, const uint32_t inNumWords, const AJAAncDataLoc &inLocInfo)
Copies payload data from an external 16-bit source into local payload memory.
std::set< UByte > NTV2DIDSet
A set of distinct NTV2DID values.
The ancillary data is in the form of a SMPTE-291 Ancillary Packet.
#define AJA_ENDIAN_32HtoN(__val__)
static const string gEmptyString
#define RCV2110DDBG(__x__)
AJAAncBufferFormat
Identifies the type of anc buffer the packet originated from: GUMP, RTP, VANC, or unknown...
static uint32_t gDestructCount(0)