14 #if defined (AJALinux) 17 #if defined(AJAANCLISTIMPL_VECTOR) 20 #if defined(AJA_USE_CPLUSPLUS11) 26 #define LOGGING_ANCLIST AJADebug::IsActive(AJA_DebugUnit_AJAAncList) 27 #define LOGGING_ANC2110RX AJADebug::IsActive(AJA_DebugUnit_Anc2110Rcv) 28 #define LOGGING_ANC2110TX AJADebug::IsActive(AJA_DebugUnit_Anc2110Xmit) 30 #define LOGMYERROR(__x__) {if (LOGGING_ANCLIST) AJA_sERROR (AJA_DebugUnit_AJAAncList, AJAFUNC << ": " << __x__);} 31 #define LOGMYWARN(__x__) {if (LOGGING_ANCLIST) AJA_sWARNING(AJA_DebugUnit_AJAAncList, AJAFUNC << ": " << __x__);} 32 #define LOGMYNOTE(__x__) {if (LOGGING_ANCLIST) AJA_sNOTICE (AJA_DebugUnit_AJAAncList, AJAFUNC << ": " << __x__);} 33 #define LOGMYINFO(__x__) {if (LOGGING_ANCLIST) AJA_sINFO (AJA_DebugUnit_AJAAncList, AJAFUNC << ": " << __x__);} 34 #define LOGMYDEBUG(__x__) {if (LOGGING_ANCLIST) AJA_sDEBUG (AJA_DebugUnit_AJAAncList, AJAFUNC << ": " << __x__);} 36 #define RCVFAIL(__x__) {if (LOGGING_ANC2110RX) AJA_sERROR (AJA_DebugUnit_Anc2110Rcv, AJAFUNC << ": " << __x__);} 37 #define RCVWARN(__x__) {if (LOGGING_ANC2110RX) AJA_sWARNING(AJA_DebugUnit_Anc2110Rcv, AJAFUNC << ": " << __x__);} 38 #define RCVNOTE(__x__) {if (LOGGING_ANC2110RX) AJA_sNOTICE (AJA_DebugUnit_Anc2110Rcv, AJAFUNC << ": " << __x__);} 39 #define RCVINFO(__x__) {if (LOGGING_ANC2110RX) AJA_sINFO (AJA_DebugUnit_Anc2110Rcv, AJAFUNC << ": " << __x__);} 40 #define RCVDBG(__x__) {if (LOGGING_ANC2110RX) AJA_sDEBUG (AJA_DebugUnit_Anc2110Rcv, AJAFUNC << ": " << __x__);} 42 #define XMTFAIL(__x__) {if (LOGGING_ANC2110TX) AJA_sERROR (AJA_DebugUnit_Anc2110Xmit, AJAFUNC << ": " << __x__);} 43 #define XMTWARN(__x__) {if (LOGGING_ANC2110TX) AJA_sWARNING(AJA_DebugUnit_Anc2110Xmit, AJAFUNC << ": " << __x__);} 44 #define XMTNOTE(__x__) {if (LOGGING_ANC2110TX) AJA_sNOTICE (AJA_DebugUnit_Anc2110Xmit, AJAFUNC << ": " << __x__);} 45 #define XMTINFO(__x__) {if (LOGGING_ANC2110TX) AJA_sINFO (AJA_DebugUnit_Anc2110Xmit, AJAFUNC << ": " << __x__);} 46 #define XMTDBG(__x__) {if (LOGGING_ANC2110TX) AJA_sDEBUG (AJA_DebugUnit_Anc2110Xmit, AJAFUNC << ": " << __x__);} 48 #if defined(AJAHostIsBigEndian) 50 #define AJA_ENDIAN_16NtoH(__val__) (__val__) 51 #define AJA_ENDIAN_16HtoN(__val__) (__val__) 52 #define AJA_ENDIAN_32NtoH(__val__) (__val__) 53 #define AJA_ENDIAN_32HtoN(__val__) (__val__) 54 #define AJA_ENDIAN_64NtoH(__val__) (__val__) 55 #define AJA_ENDIAN_64HtoN(__val__) (__val__) 58 #define AJA_ENDIAN_16NtoH(__val__) AJA_ENDIAN_SWAP16(__val__) 59 #define AJA_ENDIAN_16HtoN(__val__) AJA_ENDIAN_SWAP16(__val__) 60 #define AJA_ENDIAN_32NtoH(__val__) AJA_ENDIAN_SWAP32(__val__) 61 #define AJA_ENDIAN_32HtoN(__val__) AJA_ENDIAN_SWAP32(__val__) 62 #define AJA_ENDIAN_64NtoH(__val__) AJA_ENDIAN_SWAP64(__val__) 63 #define AJA_ENDIAN_64HtoN(__val__) AJA_ENDIAN_SWAP64(__val__) 71 unsigned numPrinted (0);
72 inOutStream <<
DECN(inData.size(),3) <<
" U32s: ";
77 if (++iter != inData.end())
79 if (numPrinted > inMaxNum)
80 {inOutStream <<
"...";
break;}
96 unsigned rtpPktNum(0);
99 inOutStream <<
"RTP PKT " <<
DEC0N(rtpPktNum,3) <<
":";
109 { inOutStream <<
xHEX0N(*it,4);
110 if (++it != inSet.end())
156 m_rcvMultiRTP (
true),
157 m_xmitMultiRTP (
false),
169 #if defined(AJA_USE_CPLUSPLUS11) 171 : m_ancList (std::move(inRHS.m_ancList)),
172 m_rcvMultiRTP (inRHS.m_rcvMultiRTP),
173 m_xmitMultiRTP (inRHS.m_xmitMultiRTP),
174 m_ignoreCS (inRHS.m_ignoreCS)
177 inRHS.m_rcvMultiRTP =
true;
178 inRHS.m_xmitMultiRTP =
false;
179 inRHS.m_ignoreCS =
false;
182 #endif // defined(AJA_USE_CPLUSPLUS11) 195 m_xmitMultiRTP = inRHS.m_xmitMultiRTP;
196 m_rcvMultiRTP = inRHS.m_rcvMultiRTP;
197 m_ignoreCS = inRHS.m_ignoreCS;
206 #if defined(AJA_USE_CPLUSPLUS11) 211 m_xmitMultiRTP = inRHS.m_xmitMultiRTP;
212 inRHS.m_xmitMultiRTP =
false;
214 m_rcvMultiRTP = inRHS.m_rcvMultiRTP;
215 inRHS.m_rcvMultiRTP =
true;
217 m_ignoreCS = inRHS.m_ignoreCS;
218 inRHS.m_ignoreCS =
false;
221 m_ancList = std::move(inRHS.m_ancList);
225 #endif // defined(AJA_USE_CPLUSPLUS11) 231 if (inIndex < m_ancList.size())
233 #if defined(AJAANCLISTIMPL_VECTOR) 234 pAncData = m_ancList[inIndex];
238 for (uint32_t i(0); i < inIndex; i++)
273 if (matchType == ancType)
290 if (matchType == ancType)
352 if (result.find(pktDIDSID) == result.end())
353 result.insert(pktDIDSID);
361 if (&inPackets ==
this)
371 m_ancList.push_back(pNewPkt);
385 const bool wasEmpty (m_ancList.empty());
392 m_ancList.push_back(pData);
394 LOGMYDEBUG(
DEC(m_ancList.size()) <<
" packet(s) stored" << (wasEmpty ?
" from" :
" after appending") <<
" packet " << pData->AsString(32));
401 uint32_t numDeleted (0);
402 const uint32_t oldSize (uint32_t(m_ancList.size()));
414 if (oldSize || numDeleted)
415 LOGMYDEBUG(numDeleted <<
" packet(s) deleted -- list emptied");
425 #if defined(AJAANCLISTIMPL_VECTOR) 427 for (it = m_ancList.begin(); it != m_ancList.end(); ++it)
430 if (it == m_ancList.end())
434 m_ancList.remove(pAncData);
437 LOGMYDEBUG(
DEC(m_ancList.size()) <<
" packet(s) remain after removing packet " << pAncData->
AsString(32));
471 return locLHS < locRHS;
479 #if defined(AJAANCLISTIMPL_VECTOR) 480 std::sort(m_ancList.begin(), m_ancList.end(),
SortByDID);
490 #if defined(AJAANCLISTIMPL_VECTOR) 491 std::sort(m_ancList.begin(), m_ancList.end(),
SortBySID);
500 #if defined(AJAANCLISTIMPL_VECTOR) 517 if (
AJA_FAILURE(pPktA->Compare(*pPktB, inIgnoreLocation, inIgnoreChecksum)))
536 const string info (pPkt->CompareWithInfo(*pPktRHS, inIgnoreLocation, inIgnoreChecksum));
539 oss <<
"Pkt " <<
DEC(ndx+1) <<
" of " <<
DEC(
CountAncillaryData()) <<
": " << pPkt->AsString() <<
" != " << pPktRHS->AsString() <<
": " << info;
554 outDiffInfo.push_back(oss.str());
562 const string info (pPkt->CompareWithInfo(*pPktRHS, inIgnoreLocation, inIgnoreChecksum));
567 <<
"LHS " << pPkt->AsString(250) << endl
568 <<
"RHS " << pPktRHS->AsString(250) << endl
570 outDiffInfo.push_back(oss.str());
573 return outDiffInfo.empty();
593 int32_t remainingSize (int32_t(inReceivedData.
GetByteCount()));
594 const uint8_t * pInputData (inReceivedData);
595 bool bMoreData (
true);
599 bool bInsertNew (
false);
601 uint32_t packetSize (0);
605 status = newAncData.
InitWithReceivedData (pInputData,
size_t(remainingSize), defaultLoc, packetSize);
611 else if (packetSize == 0)
622 else if (newAncData.
IsRaw())
639 if ((*pRaw)->GetDataLocation().OrdinalValue() == desiredLocation)
643 pContinuationPkt = *pRaw;
644 pContinuationPkt->AppendPayload(newAncData);
648 if (!pContinuationPkt)
670 rawPkts.push_back(pData);
672 m_ancList.push_back(pData);
683 remainingSize -= packetSize;
684 pInputData += packetSize;
685 if (remainingSize <= 0)
689 if (!rawPkts.empty())
692 while (!rawPkts.empty())
694 delete rawPkts.at(0);
695 rawPkts.erase(rawPkts.begin());
697 else while (
AJA_SUCCESS(status) && !rawPkts.empty())
700 m_ancList.push_back(rawPkts.back());
716 const uint32_t inFrameNum)
719 const uint8_t * pRcvData = inReceivedData;
720 const uint32_t dataSize = inReceivedData.
GetByteCount();
721 if (!pRcvData || !dataSize)
726 int32_t remainingSize (int32_t(dataSize + 0));
727 const uint8_t * pInputData (pRcvData);
728 bool bMoreData (
true);
732 uint32_t packetSize (0);
739 else if (packetSize == 0)
749 try {m_ancList.push_back(pData);}
760 remainingSize -= packetSize;
761 pInputData += packetSize;
762 if (remainingSize <= 0)
775 if (inReceivedData.empty())
783 {
LOGMYERROR(
"AJARTPAncPayloadHeader::ReadULWordVector failed, " <<
DEC(4*inReceivedData.size()) <<
" header bytes");
return AJA_STATUS_FAIL;}
789 const size_t predictedPayloadSize (RTPheader.
GetPayloadLength() /
sizeof(uint32_t));
792 uint32_t pktsAdded (0);
795 if (actualPayloadSize < predictedPayloadSize)
799 if (!actualPayloadSize)
807 for (; pktNum < numPackets &&
AJA_SUCCESS(status); pktNum++)
823 try {m_ancList.push_back(pNewPkt); pktsAdded++;}
832 {
LOGMYWARN(
DEC(pktsAdded) <<
" of " <<
DEC(numPackets) <<
" anc pkt(s) decoded from RTP pkt");}
834 LOGMYINFO(
DEC(numPackets) <<
" pkts added from RTP pkt: " << *
this);
848 if (inPacketWords.size () < 7)
868 outGumpPkt.reserve (outGumpPkt.size() + inPacketWords.size());
869 const UByteSequence::size_type dataByte1Ndx (outGumpPkt.size()+1);
870 outGumpPkt.push_back(0xFF);
871 outGumpPkt.push_back(0x80);
872 outGumpPkt[dataByte1Ndx] |= (inLoc.GetLineNumber() >> 7) & 0x0F;
873 if (inLoc.IsLumaChannel())
874 outGumpPkt[dataByte1Ndx] |= 0x20;
876 outGumpPkt[dataByte1Ndx] |= 0x10;
877 outGumpPkt.push_back (inLoc.GetLineNumber() & 0x7F);
879 while (iter != inPacketWords.end())
881 outGumpPkt.push_back(*iter & 0xFF);
912 try {m_ancList.push_back(pData);}
915 if (inFrameNum && pData->
GetDID())
931 const uint32_t inFrameNum)
936 LOGMYERROR(
"AJA_STATUS_NULL: NULL frame buffer pointer");
941 LOGMYERROR(
"AJA_STATUS_BAD_PARAM: bad NTV2FormatDescriptor");
946 LOGMYERROR(
"AJA_STATUS_BAD_PARAM: format descriptor has no VANC lines");
955 LOGMYERROR(
"AJA_STATUS_FAIL: " << inFB.
GetByteCount() <<
"-byte frame buffer smaller than " << vancBytes <<
"-byte VANC region");
988 NTV2_ASSERT(ycPackets.size() == ycHOffsets.size());
990 for (AJAAncillaryData::U16Packets::const_iterator it(ycPackets.begin()); it != ycPackets.end(); ++it, ndx++)
1006 for (AJAAncillaryData::U16Packets::const_iterator it(yPackets.begin()); it != yPackets.end(); ++it, ndxx++)
1010 for (AJAAncillaryData::U16Packets::const_iterator it(cPackets.begin()); it != cPackets.end(); ++it, ndxx++)
1021 const uint32_t inFrameNum)
1023 uint32_t RTPPacketCount (0);
1038 size_t ULWordCount (0);
1039 size_t ULWordOffset (0);
1040 unsigned retries (0);
1041 const unsigned MAX_RETRIES (4);
1043 while (ancBuffer && retries++ < MAX_RETRIES)
1055 RCVWARN(
"On RTP pkt " <<
DEC(RTPPacketCount) <<
", RTP hdr ReadFromBuffer failed at: " << ancBuffer.AsString(40));
1063 if (!ancBuffer.GetU32s (U32s, 0, ULWordCount))
1065 RCVFAIL(
"On RTP pkt " <<
DEC(RTPPacketCount) <<
", GetU32s(" <<
DEC(ULWordCount) <<
") at: " << ancBuffer.AsString(40));
1083 ULWordOffset += ULWordCount;
1085 inAncBuffer.
GetByteCount() - ULWordOffset *
sizeof(uint32_t));
1086 RCVDBG(
"Moved buffer " << inAncBuffer <<
" forward by " <<
DEC(ULWordCount) <<
" U32s: " << ancBuffer.AsString(20));
1092 {
LOGMYDEBUG(
"Success: " <<
DEC(pktsAdded) <<
" pkts added");}
1102 const uint32_t inFrameNum)
1115 {
LOGMYDEBUG(
"Success: " <<
DEC(pktsAdded) <<
" pkts added");}
1127 const uint32_t inFrameNum)
1145 const uint32_t inFrameNum)
1167 const bool inIsProgressive,
const uint32_t inF2StartLine)
1170 uint32_t actF1PktCnt (0);
1171 uint32_t actF2PktCnt (0);
1172 uint32_t pktNdx (0);
1173 size_t oldPktLengthWords (0);
1174 unsigned countOverflows (0);
1175 size_t overflowWords (0);
1180 outF1AncCounts.clear(); outF2AncCounts.clear();
1184 if (!inIsProgressive)
1186 F1U32s.clear(); F2U32s.clear();
1210 oldPktLengthWords = F1U32s.size();
1216 overflowWords += F1U32s.size() - oldPktLengthWords;
1218 while (F1U32s.size() > oldPktLengthWords)
1225 outF1U32Pkts.push_back(F1U32s);
1226 outF1AncCounts.push_back(1);
1239 oldPktLengthWords = F2U32s.size();
1245 overflowWords += F2U32s.size() - oldPktLengthWords;
1247 while (F2U32s.size() > oldPktLengthWords)
1254 outF2U32Pkts.push_back(F2U32s);
1255 outF2AncCounts.push_back(1);
1266 outF1U32Pkts.push_back(F1U32s);
1267 outF1AncCounts.push_back(uint8_t(actF1PktCnt));
1268 outF2U32Pkts.push_back(F2U32s);
1269 outF2AncCounts.push_back(uint8_t(actF2PktCnt));
1271 if (overflowWords && countOverflows)
1272 {
LOGMYWARN(
"Overflow: " <<
DEC(countOverflows) <<
" pkts skipped, " <<
DEC(overflowWords) <<
" U32s dropped");}
1273 else if (overflowWords)
1274 {
LOGMYWARN(
"Data overflow: " <<
DEC(overflowWords) <<
" U32s dropped");}
1275 else if (countOverflows)
1276 LOGMYWARN(
"Packet overflow: " <<
DEC(countOverflows) <<
" pkts skipped");
1277 XMTDBG(
"F1 (Content Only): " << outF1U32Pkts);
1278 XMTDBG(
"F2 (Content Only): " << outF2U32Pkts);
1292 uint32_t f1Size (0);
1293 uint32_t f2Size (0);
1298 uint32_t packetSize (0);
1304 f1Size += packetSize;
1306 f2Size += packetSize;
1317 NTV2Buffer F1Buffer(pF1AncData, inMaxF1Data), F2Buffer(pF2AncData, inMaxF2Data);
1318 if (!F1Buffer.IsNULL())
1322 return GetTransmitData(F1Buffer, F2Buffer, bProgressive, f2StartLine);
1327 const bool inIsProgressive,
const uint32_t inF2StartLine)
1330 size_t maxF1Data(F1Buffer), maxF2Data(F2Buffer);
1331 uint8_t *pF1AncData(F1Buffer), *pF2AncData(F2Buffer);
1333 F1Buffer.
Fill(uint64_t(0)); F2Buffer.
Fill(uint64_t(0));
1341 uint32_t pktSize(0);
1348 if (pF1AncData && maxF1Data)
1354 pF1AncData += pktSize;
1355 maxF1Data -= pktSize;
1358 else if (pF2AncData && maxF2Data)
1364 pF2AncData += pktSize;
1365 maxF2Data -= pktSize;
1374 if (inFrameBuffer.
IsNULL())
1376 LOGMYERROR(
"AJA_STATUS_NULL: null frame buffer");
1381 LOGMYERROR(
"AJA_STATUS_BAD_PARAM: Invalid format descriptor");
1384 if (!inFormatDesc.
IsVANC())
1386 LOGMYERROR(
"AJA_STATUS_BAD_PARAM: Not a VANC geometry");
1391 LOGMYERROR(
"AJA_STATUS_UNSUPPORTED: unsupported pixel format: " << inFormatDesc);
1404 const bool isSD (inFormatDesc.
IsSD());
1406 set <uint16_t> lineOffsetsWritten;
1411 ULWord smpteLine (0);
bool isF2 (
false);
1417 bool muxedOK (
false);
1428 if (loc.GetLineNumber() != smpteLine)
1435 LOGMYWARN(
"Skipped packet with invalid data channel " << loc);
1448 for (
unsigned ndx(0); ndx < u16PktComponents.size(); ndx++)
1449 pLine[ndx] = uint8_t(u16PktComponents[ndx] & 0xFF);
1453 unsigned dstNdx(loc.IsLumaChannel() ? 1 : 0);
1454 for (
unsigned srcNdx(0); srcNdx < u16PktComponents.size(); srcNdx++)
1455 pLine[dstNdx + 2*srcNdx] = uint8_t(u16PktComponents[srcNdx] & 0x00FF);
1462 while (u16PktComponents.size() < 12 || u16PktComponents.size() % 12)
1463 u16PktComponents.push_back(0x040);
1469 unsigned dstNdx (loc.IsLumaChannel() ? 1 : 0);
1477 for (
unsigned srcNdx(0); srcNdx < u16PktComponents.size(); srcNdx++)
1478 YUV16Line[dstNdx + 2*srcNdx] = u16PktComponents[srcNdx] & 0x03FF;
1484 while (YUV16Line.size() < 12 || YUV16Line.size() % 12)
1485 YUV16Line.push_back(0x040);
1496 lineOffsetsWritten.insert(uint16_t(fbLineOffset));
1497 successes.AddAncillaryData(ancData);
1500 failures.AddAncillaryData(ancData);
1507 bool success (inFormatDesc.
IsSD());
1511 if (!ancData.IsRaw())
1516 if (success && lineOffsetsWritten.find(uint16_t(lineOffset)) != lineOffsetsWritten.end())
1525 success =
AJA_SUCCESS(ancData.GenerateTransmitData(pktComponentData));
1533 lineOffsetsWritten.insert(uint16_t(lineOffset));
1534 successes.AddAncillaryData(ancData);
1537 failures.AddAncillaryData(ancData);
1540 if (failures.CountAncillaryData())
1542 if (successes.CountAncillaryData())
1554 const bool inIsF2,
const bool inIsProgressive)
1557 const string sFld (inIsF2 ?
" F2" :
" F1");
1558 const string sPrg (inIsProgressive ?
" Prg" :
" Int");
1559 ULWord u32offset(0), pktNum(1);
1561 outBytesWritten = 0;
1562 if (inRTPPkts.size() != inAncCounts.size())
1566 for (
AJAU32PktsConstIter RTPPktIter(inRTPPkts.begin()); RTPPktIter != inRTPPkts.end(); pktNum++)
1571 const bool isLastRTPPkt (++RTPPktIter == inRTPPkts.end());
1573 + origRTPPkt.size() *
sizeof(uint32_t));
1574 ostringstream pktNumInfo;
1575 pktNumInfo <<
" for RTP pkt " <<
DEC(pktNum) <<
" of " <<
DEC(totPkts);
1578 if (inIsProgressive)
1586 RTPHeader.
SetPayloadLength(uint16_t(origRTPPkt.size() *
sizeof(uint32_t)));
1597 if (!theBuffer.
PutU32s(RTPHeaderU32s, u32offset))
1598 {
LOGMYERROR(
"RTP hdr WriteBuffer failed for buffer " << theBuffer <<
" at u32offset=" <<
DEC(u32offset)
1601 u32offset +=
ULWord(RTPHeaderU32s.size());
1606 if (!theBuffer.
PutU32s(origRTPPkt, u32offset))
1607 {
LOGMYERROR(
"PutU32s failed writing " <<
DEC(origRTPPkt.size()) <<
" U32s in buffer " << theBuffer <<
" at u32offset=" <<
DEC(u32offset)
1609 LOGMYDEBUG(
"PutU32s OK @u32offset=" <<
xHEX0N(u32offset,4) <<
": " << RTPHeader << pktNumInfo.str());
1613 u32offset +=
ULWord(origRTPPkt.size());
1620 outBytesWritten = u32offset *
ULWord(
sizeof(uint32_t));
1622 LOGMYDEBUG(
DEC(totPkts) <<
" RTP pkt(s), " <<
DEC(u32offset) <<
" U32s (" <<
DEC(outBytesWritten)
1623 <<
" bytes) written for" << sFld << sPrg);
1629 const bool inIsProgressive,
const uint32_t inF2StartLine)
1634 uint32_t byteCount(0);
1637 F1Buffer.
Fill(uint64_t(0)); F2Buffer.
Fill(uint64_t(0));
1641 result =
GetRTPPackets (F1U32Pkts, F2U32Pkts, F1AncCounts, F2AncCounts, inIsProgressive, inF2StartLine);
1652 result =
WriteRTPPackets (F1Buffer, byteCount, F1U32Pkts, F1AncCounts,
false, inIsProgressive);
1657 if (!inIsProgressive)
1658 result =
WriteRTPPackets (F2Buffer, byteCount, F2U32Pkts, F2AncCounts,
true, inIsProgressive);
1666 const bool inIsProgressive,
const uint32_t inF2StartLine)
1668 outF1ByteCount = outF2ByteCount = 0;
1673 AJAStatus result (
GetRTPPackets (F1U32Pkts, F2U32Pkts, F1AncCounts, F2AncCounts, inIsProgressive, inF2StartLine));
1678 result =
WriteRTPPackets (nullBuffer, outF1ByteCount, F1U32Pkts, F1AncCounts,
false, inIsProgressive);
1680 result =
WriteRTPPackets (nullBuffer, outF2ByteCount, F2U32Pkts, F2AncCounts,
true, inIsProgressive);
1693 inOutStream <<
"Pkt" <<
DEC0N(++num,3) <<
": " << pPkt->
AsString(inDumpPayload ? 16 : 0);
1694 if (++it != m_ancList.end())
1695 inOutStream << endl;
1703 if (!inSrc || !outDst)
1708 uint8_t * srcPtr = inSrc;
1709 uint8_t * ptr = srcPtr;
1710 size_t srcBufSize = inSrc;
1711 uint8_t * tgtPtr = outDst;
1712 size_t uncopied = 0;
1715 const size_t kGUMPHeaderSize(7);
1717 for (
size_t ndx(0); ndx < srcBufSize; )
1719 if (ptr[0] == 0xff && (ndx + kGUMPHeaderSize) < srcBufSize)
1721 bool bFiltered{
false};
1722 const uint8_t payloadSize(ptr[5]);
1726 else if (ptr[3] == 0x60 && ptr[4] == 0x60 && payloadSize == 16)
1728 else if (ptr[3] == 0x41 && ptr[4] == 0x01 && payloadSize == 4)
1730 else if (ptr[3] == 0xF4 && ptr[4] == 0x00 && payloadSize == 16)
1734 const uint16_t lineNum (uint16_t((ptr[1] & 0x0F) << 7) + uint16_t(ptr[2] & 0x7F));
1735 bFiltered = (ptr[1] & 0x40) && (lineNum == 14 || lineNum == 277);
1741 ::memcpy(tgtPtr, srcPtr, uncopied);
1744 srcPtr += uncopied + payloadSize + kGUMPHeaderSize;
1746 ndx += payloadSize + kGUMPHeaderSize;
1753 ptr += payloadSize + kGUMPHeaderSize;
1754 ndx += payloadSize + kGUMPHeaderSize;
1755 uncopied += payloadSize + kGUMPHeaderSize;
1759 {ptr++; ndx++; uncopied++;}
1763 ::memcpy(tgtPtr, srcPtr, uncopied);
1821 AJAAncillaryAnalogTypeMap::const_iterator it (
gAnalogTypeMap.find (inLineNum));
1823 ancType = it->second;
static bool SortBySID(AJAAncillaryData *lhs, AJAAncillaryData *rhs)
virtual AJAStatus AddReceivedAuxiliaryData(const NTV2Buffer &inReceivedData, const uint32_t inFrameNum=0)
Parse "raw" HDMI auxillary data bytes received from hardware (ingest) into separate AJAAncillaryData ...
virtual uint8_t GetDID(void) const
std::set< AJAAncPktDIDSID > AJAAncPktDIDSIDSet
Set of distinct packet DID/SIDs (New in SDK 16.0)
#define AJA_SUCCESS(_status_)
virtual AJAStatus GetTransmitData(NTV2Buffer &F1Buffer, NTV2Buffer &F2Buffer, const bool inIsProgressive=true, const uint32_t inF2StartLine=0)
Encodes my AJAAncillaryData packets into the given buffers in the default SDI Anc Buffer Data Format ...
virtual AJAStatus AddReceivedAncillaryData(const NTV2Buffer &inReceivedData, const uint32_t inFrameNum=0)
Parse "raw" ancillary data bytes received from hardware (ingest) – see SDI Anc Buffer Data Format –...
virtual AJAStatus GetAncillaryDataTransmitSize(const bool inIsProgressive, const uint32_t inF2StartLine, uint32_t &outF1ByteCount, uint32_t &outF2ByteCount)
Answers with the sizes of the buffers (one for field 1, one for field 2) needed to hold the anc data ...
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 ...
virtual AJAStatus SortListByLocation(void)
Sort the AncillaryDataList by "location", i.e. where in the video (field, line num, HANC/VANC) the data came from or will be inserted to.
virtual uint32_t CountAncillaryData(void) const
Answers with the number of AJAAncillaryData objects I contain (any/all types).
bool YUVComponentsTo10BitYUVPackedBuffer(const std::vector< uint16_t > &inYCbCrLine, NTV2Buffer &inFrameBuffer, const NTV2FormatDescriptor &inDescriptor, const UWord inLineOffset)
Packs up to one raster line of uint16_t YUV components into an NTV2_FBF_10BIT_YCBCR frame buffer...
virtual AJAStatus GetRawPacketSize(uint32_t &outPacketSize) const
Returns the number of "raw" ancillary data bytes that will be generated by AJAAncillaryData::Generate...
#define LOGMYERROR(__x__)
virtual AJAAncillaryData * Clone(void) const
virtual uint8_t GetSID(void) const
virtual AJAAncPktDIDSIDSet GetAncillaryPacketIDs(void) const
static const uint32_t MAX_ANC_PKTS_PER_RTP_PKT(0x000000FF)
AJAAncDataLoc & SetHorizontalOffset(uint16_t inHOffset)
Specifies the horizontal packet position in the raster.
#define DEC0N(__x__, __n__)
NTV2FrameBufferFormat
Identifies a particular video frame buffer pixel format. See Device Frame Buffer Formats for details...
Ancillary data found between SAV and EAV (.
Declares the AJADebug class.
virtual AJAAncillaryData * GetAncillaryDataAtIndex(const uint32_t inIndex) const
Answers with the AJAAncillaryData object at the given index.
size_t GetByteCount(void) const
virtual AJAStatus DeleteAncillaryData(AJAAncillaryData *pInAncData)
Removes all copies of the AJAAncillaryData object from me and deletes the object itself.
Only look in luma samples.
virtual AJAStatus SortListByDID(void)
Sort the AncillaryDataList by DataID (DID) value.
#define AJA_FAILURE(_status_)
virtual const AJAAncDataLoc & GetDataLocation(void) const
AJAAncDataType
Identifies the ancillary data types that are known to this module.
ULWordSequence::const_iterator ULWordSequenceConstIter
A handy const iterator for iterating over a ULWordSequence.
static bool gIncludeZeroLengthPackets(false)
ostream & operator<<(ostream &inOutStream, const AJAU32Pkts &inPkts)
#define ToAJAAncPktDIDSID(_d_, _s_)
struct AJAAncDataLoc AJAAncDataLoc
Defines where the ancillary data can be found within a video stream.
static AJAAncDataType GuessAncillaryDataType(const AJAAncillaryData &inAncData)
Given a generic AJAAncillaryData object, attempts to guess what kind of specific AJAAncillaryData obj...
static AJAStatus GetAnalogAncillaryDataTypeMap(AJAAncillaryAnalogTypeMap &outMap)
Returns a copy of the global Analog Ancillary Data Type map.
virtual std::string AsString(const uint16_t inDumpMaxBytes=0) const
uint64_t OrdinalValue(void) const
virtual std::ostream & Print(std::ostream &oss, const bool inDetailed=true) const
Dumps a human-readable description of every packet in my list to the given output stream...
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...
std::map< uint16_t, AJAAncDataType > AJAAncillaryAnalogTypeMap
Associates certain frame line numbers with specific types of "raw" or "analog" ancillary data...
static bool SortByDID(AJAAncillaryData *lhs, AJAAncillaryData *rhs)
virtual void Clear(void)
Frees my allocated memory, if any, and resets my members to their default values. ...
AJAU32Pkts::const_iterator AJAU32PktsConstIter
Handy const iterator over AJAU32Pkts.
virtual uint32_t GetFrameID(void) const
static uint32_t ENDIAN_32NtoH(const uint32_t inValue)
static bool StripNativeInserterGUMPPackets(const NTV2Buffer &inSrc, NTV2Buffer &outDst)
Copies GUMP from inSrc to outDst buffers, but removes ATC, VPID, VITC, EDH & raw/analog packets...
#define LOGMYDEBUG(__x__)
static AJAStatus AddFromDeviceAuxBuffer(const NTV2Buffer &inAuxBuffer, AJAAncillaryList &outPacketList, const uint32_t inFrameNum=0)
Appends whatever can be decoded from the given device HDIM aux buffer to the AJAAncillaryList.
virtual uint16_t GetLocationLineNumber(void) const
static AJALock gAnalogTypeMapMutex
#define NTV2_ASSERT(_expr_)
static uint32_t gExcludedZeroLengthPackets(0)
Defines where the ancillary data can be found within a video stream.
virtual AJAAncDataType GetAncillaryDataType(void) const
virtual AJAAncDataType GetAnalogAncillaryDataType(const AJAAncillaryData &inAncData)
static AJAStatus SetFromDeviceAuxBuffers(const NTV2Buffer &inF1AuxBuffer, const NTV2Buffer &inF2AuxBuffer, AJAAncillaryList &outPackets, const uint32_t inFrameNum=0)
Returns all HDMI Aux data packets found in the given F1 and F2 aux data buffers.
std::vector< uint8_t > UByteSequence
An ordered sequence of UByte (uint8_t) values.
virtual bool AllowMultiRTPTransmit(void) const
Answers true if multiple RTP packets will be transmitted/encoded. The default behavior is to transmit...
bool Fill(const T &inValue)
Fills me with the given scalar value.
virtual AJAAncillaryData & SetFrameID(const uint32_t inFrameID)
Sets my originating frame identifier.
static string ULWordSequenceToStringBE(const ULWordSequence &inData, const size_t inMaxNum=32)
bool UnpackLine_10BitYUVtoU16s(std::vector< uint16_t > &outYCbCrLine, const NTV2Buffer &inFrameBuffer, const NTV2FormatDescriptor &inDescriptor, const UWord inLineOffset)
Unpacks up to one raster line of an NTV2_FBF_10BIT_YCBCR frame buffer into an array of uint16_t value...
bool IsProvidedByClient(void) const
std::vector< U16Packet > U16Packets
An ordered sequence of zero or more U16Packet values.
AJAAncillaryDataList::iterator AJAAncDataListIter
Handy non-const iterator for iterating over members of an AJAAncillaryDataList.
const uint8_t AJAAncillaryDataWildcard_DID
Includes data that is valid, but we don't recognize.
static AJAStatus SetFromVANCData(const NTV2Buffer &inFrameBuffer, const NTV2FormatDescriptor &inFormatDesc, AJAAncillaryList &outPackets, const uint32_t inFrameNum=0)
Returns all packets found in the VANC lines of the given NTV2 frame buffer.
virtual AJAStatus Compare(const AJAAncillaryList &inCompareList, const bool inIgnoreLocation=true, const bool inIgnoreChecksum=true) const
Compares me with another list.
virtual uint32_t CountAncillaryDataWithID(const uint8_t inDID, const uint8_t inSID) const
Answers with the number of AncillaryData objects having the given DataID and SecondaryID.
static AJAStatus ClearAnalogAncillaryDataTypeMap(void)
Clears my global Analog Ancillary Data Type map.
static const size_t MAX_RTP_PKT_LENGTH_WORDS((MAX_RTP_PKT_LENGTH_BYTES+1)/sizeof(uint32_t) - 1)
virtual AJAAncillaryData & SetBufferFormat(const AJAAncBufferFormat inFmt)
Sets my originating buffer format.
std::vector< AJAAncillaryData * > AJAAncillaryDataList
static void BumpZeroLengthPacketCount(void)
static const size_t MAX_RTP_PKT_LENGTH_BYTES(0x0000FFFF)
virtual AJAStatus Clear(void)
Removes and frees all of my AJAAncillaryData objects.
virtual AJAAncillaryData * GetAncillaryDataWithType(const AJAAncDataType inMatchType, const uint32_t inIndex=0) const
Answers with the AJAAncillaryData object having the given type and index.
The ancillary data is associated with the chrominance (C) channel of the video stream.
The ancillary data is associated with the luminance (Y) channel of the video stream.
static AJAStatus SetFromDeviceAncBuffers(const NTV2Buffer &inF1AncBuffer, const NTV2Buffer &inF2AncBuffer, AJAAncillaryList &outPackets, const uint32_t inFrameNum=0)
Returns all ancillary data packets found in the given F1 and F2 ancillary data buffers.
virtual AJAStatus AddAncillaryData(const AJAAncillaryList &inPackets)
Appends a copy of the given list's packets to me.
virtual AJAStatus ParsePayloadData(void)
Parses (interprets) the "local" ancillary data from my payload data.
std::vector< uint16_t > UWordSequence
An ordered sequence of UWord (uint16_t) values.
virtual bool AllowMultiRTPReceive(void) const
Answers true if multiple RTP packets are allowed for capture/receive. The default behavior is to proc...
AJAAncillaryList()
Instantiate and initialize with a default set of values.
virtual AJAAncillaryList & operator=(const AJAAncillaryList &inRHS)
Assignment operator – replaces my contents with the right-hand-side value.
UWordSequence::const_iterator UWordSequenceConstIter
A handy const iterator for iterating over a UWordSequence.
static int32_t Increment(int32_t volatile *pTarget)
static AJAAncDataType GetAnalogAncillaryDataTypeForLine(const uint16_t inLineNum)
Answers with the ancillary data type associated with the designated line.
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...
virtual AJAStatus GetVANCTransmitData(NTV2Buffer &inFrameBuffer, const NTV2FormatDescriptor &inFormatDesc)
Writes my AJAAncillaryData objects into the given tall/taller frame buffer having the given raster/fo...
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 AddVANCData(const UWordSequence &inPacketWords, const AJAAncillaryDataLocation &inLocation, const uint32_t inFrameNum=0)
Adds the packet that originated in the VANC lines of an NTV2 frame buffer to my list.
virtual std::string CompareWithInfo(const AJAAncillaryList &inCompareList, const bool inIgnoreLocation=true, const bool inIgnoreChecksum=true) const
Compares me with another list and returns a std::string that contains a human-readable explanation of...
static bool BufferHasGUMPData(const NTV2Buffer &inBuffer)
static uint32_t GetExcludedZeroLengthPacketCount(void)
virtual AJAAncillaryData * GetAncillaryDataWithID(const uint8_t inDID, const uint8_t inSID, const uint32_t inIndex=0) const
Answers with the AJAAncillaryData object having the given DataID and SecondaryID, at the given index...
virtual AJAStatus GetIPTransmitDataLength(uint32_t &outF1ByteCount, uint32_t &outF2ByteCount, const bool inIsProgressive=true, const uint32_t inF2StartLine=0)
Answers with the number of bytes required to store IP/RTP for my AJAAncillaryData packets in RTP Anc ...
static ostream & PrintULWordsBE(ostream &inOutStream, const ULWordSequence &inData, const size_t inMaxNum=32)
static AJAStatus SetAnalogAncillaryDataTypeForLine(const uint16_t inLineNum, const AJAAncDataType inType)
Sets (or changes) the map entry for the designated line to the designated type.
std::vector< ULWordSequence > AJAU32Pkts
Ordered sequence of U32 RTP packets (U32s in network byte order)
static void SetIncludeZeroLengthPackets(const bool inExclude)
Sets whether or not zero-length packets are included or not.
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.).
virtual AJAStatus SortListBySID(void)
Sort the AncillaryDataList by Secondary ID (SID) value.
Declares the AJAAtomic class.
static bool Unpack8BitYCbCrToU16sVANCLineSD(const void *pInYUV8Line, UWordSequence &outU16YUVLine, const uint32_t inNumPixels)
SD version of Unpack8BitYCbCrToU16sVANCLine.
bool PutU32s(const ULWordSequence &inU32s, const size_t inU32Offset=0, const bool inByteSwap=false)
Copies a vector of unsigned 32-bit values into me.
#define AJA_ENDIAN_32NtoH(__val__)
virtual uint32_t CountAncillaryDataWithType(const AJAAncDataType inMatchType) const
Answers with the number of AJAAncillaryData objects having the given type.
Declaration of the AJAAncillaryDataFactory class.
AJAAncillaryDataList::const_iterator AJAAncDataListConstIter
Handy const iterator for iterating over members of an AJAAncillaryDataList.
#define NTV2_IS_SD_STANDARD(__s__)
Declares numerous NTV2 utility functions.
virtual bool IsDigital(void) const
virtual bool IgnoreChecksumErrors(void) const
Answers if checksum errors are to be ignored or not. The default behavior is to not ignore them...
static AJALock gGlobalLock
The ancillary data is associated with Link A of the video stream.
virtual AJAStatus RemoveAncillaryData(AJAAncillaryData *pInAncData)
Removes all copies of the AJAAncillaryData object from me.
virtual AJAStatus ParseAllAncillaryData(void)
Sends a "ParsePayloadData" command to all of my AJAAncillaryData objects.
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...
virtual AJAStatus GetAncillaryDataTransmitData(const bool inIsProgressive, const uint32_t inF2StartLine, uint8_t *pOutF1AncData, const uint32_t inF1ByteCountMax, uint8_t *pOutF2AncData, const uint32_t inF2ByteCountMax)
Builds one or two ancillary data buffers (one for field 1, one for field 2) with the anc data inserte...
Look both luma and chroma samples (SD only)
virtual AJAAncDataCoding GetDataCoding(void) const
virtual AJAStatus GetIPTransmitData(NTV2Buffer &F1Buffer, NTV2Buffer &F2Buffer, const bool inIsProgressive=true, const uint32_t inF2StartLine=0)
Explicitly encodes my AJAAncillaryData packets into the given buffers in RTP Anc Buffer Data Format ...
static AJAAncillaryAnalogTypeMap gAnalogTypeMap
#define xHEX0N(__x__, __n__)
static AJAStatus WriteRTPPackets(NTV2Buffer &theBuffer, uint32_t &outBytesWritten, const AJAU32Pkts &inRTPPkts, const AJAAncPktCounts &inAncCounts, const bool inIsF2, const bool inIsProgressive)
Fills the buffer with the given RTP packets.
#define IS_VALID_AJAAncDataChannel(_x_)
std::string NTV2FrameBufferFormatToString(const NTV2FrameBufferFormat inValue, const bool inForRetailDisplay=false)
virtual bool IsRaw(void) const
AJAAncPktDIDSIDSet::const_iterator AJAAncPktDIDSIDSetConstIter
Handy const iterator for AJAAncPktDIDSIDSet (New in SDK 16.0)
static AJAStatus AddFromDeviceAncBuffer(const NTV2Buffer &inAncBuffer, AJAAncillaryList &outPacketList, const uint32_t inFrameNum=0)
Appends whatever can be decoded from the given device Anc buffer to the AJAAncillaryList.
SD ONLY – The ancillary data is associated with both the chroma and luma channels.
AJAAncDataLink
Identifies which link of a video stream the ancillary data is associated with.
const uint8_t AJAAncillaryDataWildcard_SID
virtual AJAStatus GetRTPPackets(AJAU32Pkts &outF1U32Pkts, AJAU32Pkts &outF2U32Pkts, AJAAncPktCounts &outF1AncCounts, AJAAncPktCounts &outF2AncCounts, const bool inIsProgressive, const uint32_t inF2StartLine)
Answers with my F1 & F2 SMPTE anc packets encoded as RTP ULWordSequences. The returned ULWords are al...
std::string AJAStatusToString(const AJAStatus inStatus, const bool inDetailed)
std::vector< uint32_t > ULWordSequence
An ordered sequence of ULWord (uint32_t) values.
virtual uint32_t GetDC(void) const
void * GetHostPointer(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...
static AJAAncillaryData * Create(const AJAAncDataType inAncType, const AJAAncillaryData &inAncData)
Creates a new particular subtype of AJAAncillaryData object.
Declares the AJAAncillaryList class.
void * GetHostAddress(const ULWord inByteOffset, const bool inFromEnd=false) const
#define DECN(__x__, __n__)
Only look in chroma samples.
static bool IsIncludingZeroLengthPackets(void)
static AJAStatus AppendUWordPacketToGump(UByteSequence &outGumpPkt, const UWordSequence &inPacketWords, const AJAAncDataLoc inLoc=AJAAncDataLoc(AJAAncDataLink_A, AJAAncDataChannel_Y, AJAAncDataSpace_VANC, 0))
CEA608 SD Closed Captioning ("Line 21" waveform)
static bool SortByLocation(AJAAncillaryData *lhs, AJAAncillaryData *rhs)
I am an ordered collection of AJAAncillaryData instances which represent one or more SMPTE 291 data p...
UByteSequence AJAAncPktCounts
Ordered sequence of SMPTE Anc packet counts.
virtual ~AJAAncillaryList()
My destructor.
The ancillary data is in the form of a SMPTE-291 Ancillary Packet.
static AJAStatus SetAnalogAncillaryDataTypeMap(const AJAAncillaryAnalogTypeMap &inMap)
Copies the given map to the global Analog Ancillary Data Type map.
#define IS_VALID_AJAAncDataType(_x_)
static void ResetExcludedZeroLengthPacketCount(void)
Resets my tally of excluded zero-length packets to zero.