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)
1144 const uint32_t inFrameNum)
1166 const bool inIsProgressive,
const uint32_t inF2StartLine)
1169 uint32_t actF1PktCnt (0);
1170 uint32_t actF2PktCnt (0);
1171 uint32_t pktNdx (0);
1172 size_t oldPktLengthWords (0);
1173 unsigned countOverflows (0);
1174 size_t overflowWords (0);
1179 outF1AncCounts.clear(); outF2AncCounts.clear();
1183 if (!inIsProgressive)
1185 F1U32s.clear(); F2U32s.clear();
1209 oldPktLengthWords = F1U32s.size();
1215 overflowWords += F1U32s.size() - oldPktLengthWords;
1217 while (F1U32s.size() > oldPktLengthWords)
1224 outF1U32Pkts.push_back(F1U32s);
1225 outF1AncCounts.push_back(1);
1238 oldPktLengthWords = F2U32s.size();
1244 overflowWords += F2U32s.size() - oldPktLengthWords;
1246 while (F2U32s.size() > oldPktLengthWords)
1253 outF2U32Pkts.push_back(F2U32s);
1254 outF2AncCounts.push_back(1);
1265 outF1U32Pkts.push_back(F1U32s);
1266 outF1AncCounts.push_back(uint8_t(actF1PktCnt));
1267 outF2U32Pkts.push_back(F2U32s);
1268 outF2AncCounts.push_back(uint8_t(actF2PktCnt));
1270 if (overflowWords && countOverflows)
1271 {
LOGMYWARN(
"Overflow: " <<
DEC(countOverflows) <<
" pkts skipped, " <<
DEC(overflowWords) <<
" U32s dropped");}
1272 else if (overflowWords)
1273 {
LOGMYWARN(
"Data overflow: " <<
DEC(overflowWords) <<
" U32s dropped");}
1274 else if (countOverflows)
1275 LOGMYWARN(
"Packet overflow: " <<
DEC(countOverflows) <<
" pkts skipped");
1276 XMTDBG(
"F1 (Content Only): " << outF1U32Pkts);
1277 XMTDBG(
"F2 (Content Only): " << outF2U32Pkts);
1291 uint32_t f1Size (0);
1292 uint32_t f2Size (0);
1297 uint32_t packetSize (0);
1303 f1Size += packetSize;
1305 f2Size += packetSize;
1316 NTV2Buffer F1Buffer(pF1AncData, inMaxF1Data), F2Buffer(pF2AncData, inMaxF2Data);
1317 if (!F1Buffer.IsNULL())
1321 return GetTransmitData(F1Buffer, F2Buffer, bProgressive, f2StartLine);
1326 const bool inIsProgressive,
const uint32_t inF2StartLine)
1329 size_t maxF1Data(F1Buffer), maxF2Data(F2Buffer);
1330 uint8_t *pF1AncData(F1Buffer), *pF2AncData(F2Buffer);
1332 F1Buffer.
Fill(uint64_t(0)); F2Buffer.
Fill(uint64_t(0));
1340 uint32_t pktSize(0);
1347 if (pF1AncData && maxF1Data)
1353 pF1AncData += pktSize;
1354 maxF1Data -= pktSize;
1357 else if (pF2AncData && maxF2Data)
1363 pF2AncData += pktSize;
1364 maxF2Data -= pktSize;
1373 if (inFrameBuffer.
IsNULL())
1375 LOGMYERROR(
"AJA_STATUS_NULL: null frame buffer");
1380 LOGMYERROR(
"AJA_STATUS_BAD_PARAM: Invalid format descriptor");
1383 if (!inFormatDesc.
IsVANC())
1385 LOGMYERROR(
"AJA_STATUS_BAD_PARAM: Not a VANC geometry");
1390 LOGMYERROR(
"AJA_STATUS_UNSUPPORTED: unsupported pixel format: " << inFormatDesc);
1403 const bool isSD (inFormatDesc.
IsSD());
1405 set <uint16_t> lineOffsetsWritten;
1410 ULWord smpteLine (0);
bool isF2 (
false);
1416 bool muxedOK (
false);
1427 if (loc.GetLineNumber() != smpteLine)
1434 LOGMYWARN(
"Skipped packet with invalid data channel " << loc);
1447 for (
unsigned ndx(0); ndx < u16PktComponents.size(); ndx++)
1448 pLine[ndx] = uint8_t(u16PktComponents[ndx] & 0xFF);
1452 unsigned dstNdx(loc.IsLumaChannel() ? 1 : 0);
1453 for (
unsigned srcNdx(0); srcNdx < u16PktComponents.size(); srcNdx++)
1454 pLine[dstNdx + 2*srcNdx] = uint8_t(u16PktComponents[srcNdx] & 0x00FF);
1461 while (u16PktComponents.size() < 12 || u16PktComponents.size() % 12)
1462 u16PktComponents.push_back(0x040);
1468 unsigned dstNdx (loc.IsLumaChannel() ? 1 : 0);
1476 for (
unsigned srcNdx(0); srcNdx < u16PktComponents.size(); srcNdx++)
1477 YUV16Line[dstNdx + 2*srcNdx] = u16PktComponents[srcNdx] & 0x03FF;
1483 while (YUV16Line.size() < 12 || YUV16Line.size() % 12)
1484 YUV16Line.push_back(0x040);
1495 lineOffsetsWritten.insert(uint16_t(fbLineOffset));
1496 successes.AddAncillaryData(ancData);
1499 failures.AddAncillaryData(ancData);
1506 bool success (inFormatDesc.
IsSD());
1510 if (!ancData.IsRaw())
1515 if (success && lineOffsetsWritten.find(uint16_t(lineOffset)) != lineOffsetsWritten.end())
1524 success =
AJA_SUCCESS(ancData.GenerateTransmitData(pktComponentData));
1532 lineOffsetsWritten.insert(uint16_t(lineOffset));
1533 successes.AddAncillaryData(ancData);
1536 failures.AddAncillaryData(ancData);
1539 if (failures.CountAncillaryData())
1541 if (successes.CountAncillaryData())
1553 const bool inIsF2,
const bool inIsProgressive)
1556 const string sFld (inIsF2 ?
" F2" :
" F1");
1557 const string sPrg (inIsProgressive ?
" Prg" :
" Int");
1558 ULWord u32offset(0), pktNum(1);
1560 outBytesWritten = 0;
1561 if (inRTPPkts.size() != inAncCounts.size())
1565 for (
AJAU32PktsConstIter RTPPktIter(inRTPPkts.begin()); RTPPktIter != inRTPPkts.end(); pktNum++)
1570 const bool isLastRTPPkt (++RTPPktIter == inRTPPkts.end());
1572 + origRTPPkt.size() *
sizeof(uint32_t));
1573 ostringstream pktNumInfo;
1574 pktNumInfo <<
" for RTP pkt " <<
DEC(pktNum) <<
" of " <<
DEC(totPkts);
1577 if (inIsProgressive)
1585 RTPHeader.
SetPayloadLength(uint16_t(origRTPPkt.size() *
sizeof(uint32_t)));
1596 if (!theBuffer.
PutU32s(RTPHeaderU32s, u32offset))
1597 {
LOGMYERROR(
"RTP hdr WriteBuffer failed for buffer " << theBuffer <<
" at u32offset=" <<
DEC(u32offset)
1600 u32offset +=
ULWord(RTPHeaderU32s.size());
1605 if (!theBuffer.
PutU32s(origRTPPkt, u32offset))
1606 {
LOGMYERROR(
"PutU32s failed writing " <<
DEC(origRTPPkt.size()) <<
" U32s in buffer " << theBuffer <<
" at u32offset=" <<
DEC(u32offset)
1608 LOGMYDEBUG(
"PutU32s OK @u32offset=" <<
xHEX0N(u32offset,4) <<
": " << RTPHeader << pktNumInfo.str());
1612 u32offset +=
ULWord(origRTPPkt.size());
1619 outBytesWritten = u32offset *
ULWord(
sizeof(uint32_t));
1621 LOGMYDEBUG(
DEC(totPkts) <<
" RTP pkt(s), " <<
DEC(u32offset) <<
" U32s (" <<
DEC(outBytesWritten)
1622 <<
" bytes) written for" << sFld << sPrg);
1628 const bool inIsProgressive,
const uint32_t inF2StartLine)
1633 uint32_t byteCount(0);
1636 F1Buffer.
Fill(uint64_t(0)); F2Buffer.
Fill(uint64_t(0));
1640 result =
GetRTPPackets (F1U32Pkts, F2U32Pkts, F1AncCounts, F2AncCounts, inIsProgressive, inF2StartLine);
1651 result =
WriteRTPPackets (F1Buffer, byteCount, F1U32Pkts, F1AncCounts,
false, inIsProgressive);
1656 if (!inIsProgressive)
1657 result =
WriteRTPPackets (F2Buffer, byteCount, F2U32Pkts, F2AncCounts,
true, inIsProgressive);
1665 const bool inIsProgressive,
const uint32_t inF2StartLine)
1667 outF1ByteCount = outF2ByteCount = 0;
1672 AJAStatus result (
GetRTPPackets (F1U32Pkts, F2U32Pkts, F1AncCounts, F2AncCounts, inIsProgressive, inF2StartLine));
1677 result =
WriteRTPPackets (nullBuffer, outF1ByteCount, F1U32Pkts, F1AncCounts,
false, inIsProgressive);
1679 result =
WriteRTPPackets (nullBuffer, outF2ByteCount, F2U32Pkts, F2AncCounts,
true, inIsProgressive);
1692 inOutStream <<
"Pkt" <<
DEC0N(++num,3) <<
": " << pPkt->
AsString(inDumpPayload ? 16 : 0);
1693 if (++it != m_ancList.end())
1694 inOutStream << endl;
1702 if (!inSrc || !outDst)
1707 uint8_t * srcPtr = inSrc;
1708 uint8_t * ptr = srcPtr;
1709 size_t srcBufSize = inSrc;
1710 uint8_t * tgtPtr = outDst;
1711 size_t uncopied = 0;
1714 const size_t kGUMPHeaderSize(7);
1716 for (
size_t ndx(0); ndx < srcBufSize; )
1718 if (ptr[0] == 0xff && (ndx + kGUMPHeaderSize) < srcBufSize)
1720 bool bFiltered{
false};
1721 const uint8_t payloadSize(ptr[5]);
1725 else if (ptr[3] == 0x60 && ptr[4] == 0x60 && payloadSize == 16)
1727 else if (ptr[3] == 0x41 && ptr[4] == 0x01 && payloadSize == 4)
1729 else if (ptr[3] == 0xF4 && ptr[4] == 0x00 && payloadSize == 16)
1733 const uint16_t lineNum (uint16_t((ptr[1] & 0x0F) << 7) + uint16_t(ptr[2] & 0x7F));
1734 bFiltered = (ptr[1] & 0x40) && (lineNum == 14 || lineNum == 277);
1740 ::memcpy(tgtPtr, srcPtr, uncopied);
1743 srcPtr += uncopied + payloadSize + kGUMPHeaderSize;
1745 ndx += payloadSize + kGUMPHeaderSize;
1752 ptr += payloadSize + kGUMPHeaderSize;
1753 ndx += payloadSize + kGUMPHeaderSize;
1754 uncopied += payloadSize + kGUMPHeaderSize;
1758 {ptr++; ndx++; uncopied++;}
1762 ::memcpy(tgtPtr, srcPtr, uncopied);
1820 AJAAncillaryAnalogTypeMap::const_iterator it (
gAnalogTypeMap.find (inLineNum));
1822 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.
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)
ULWord GetByteCount(void) const
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.