AJA NTV2 SDK  17.5.0.1492
NTV2 SDK 17.5.0.1492
ancillarylist.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
8 #include "ancillarylist.h"
9 #include "ancillarydatafactory.h"
10 #include "ajabase/system/debug.h"
12 #include "ajabase/system/atomic.h"
13 #include "ajabase/system/lock.h"
14 #if defined (AJALinux)
15  #include <string.h> // For memcpy
16 #endif // AJALinux
17 #if defined(AJAANCLISTIMPL_VECTOR)
18  #include <algorithm>
19 #endif
20 #if defined(AJA_USE_CPLUSPLUS11)
21  #include <utility> // For std::move
22 #endif
23 
24 using namespace std;
25 
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)
29 
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__);}
35 
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__);}
41 
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__);}
47 
48 #if defined(AJAHostIsBigEndian)
49  // Host is BigEndian (BE)
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__)
56 #else
57  // Host is LittleEndian (LE)
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__)
64 #endif
65 
66 static inline uint32_t ENDIAN_32NtoH(const uint32_t inValue) {return AJA_ENDIAN_32NtoH(inValue);}
67 //static inline uint32_t ENDIAN_32HtoN(const uint32_t inValue) {return AJA_ENDIAN_32HtoN(inValue);}
68 
69 static ostream & PrintULWordsBE (ostream & inOutStream, const ULWordSequence & inData, const size_t inMaxNum = 32)
70 {
71  unsigned numPrinted (0);
72  inOutStream << DECN(inData.size(),3) << " U32s: ";
73  for (ULWordSequenceConstIter iter(inData.begin()); iter != inData.end(); )
74  {
75  inOutStream << HEX0N(ENDIAN_32NtoH(*iter),8);
76  numPrinted++;
77  if (++iter != inData.end())
78  {
79  if (numPrinted > inMaxNum)
80  {inOutStream << "..."; break;}
81  inOutStream << " ";
82  }
83  }
84  return inOutStream;
85 }
86 
87 static string ULWordSequenceToStringBE (const ULWordSequence & inData, const size_t inMaxNum = 32)
88 {
89  ostringstream oss;
90  ::PrintULWordsBE (oss, inData, inMaxNum);
91  return oss.str();
92 }
93 
94 ostream & operator << (ostream & inOutStream, const AJAU32Pkts & inPkts)
95 {
96  unsigned rtpPktNum(0);
97  for (AJAU32PktsConstIter pktIter(inPkts.begin()); pktIter != inPkts.end(); ++pktIter)
98  { ++rtpPktNum;
99  inOutStream << "RTP PKT " << DEC0N(rtpPktNum,3) << ":";
100  ::PrintULWordsBE(inOutStream, *pktIter);
101  inOutStream << endl;
102  } // for each RTP packet
103  return inOutStream;
104 }
105 
106 ostream & operator << (ostream & inOutStream, const AJAAncPktDIDSIDSet & inSet)
107 {
108  for (AJAAncPktDIDSIDSetConstIter it(inSet.begin()); it != inSet.end(); )
109  { inOutStream << xHEX0N(*it,4);
110  if (++it != inSet.end())
111  inOutStream << " ";
112  } // for each DID/SID pair
113  return inOutStream;
114 }
115 
116 
117 
119 
120 
121 static bool gIncludeZeroLengthPackets (false);
122 static uint32_t gExcludedZeroLengthPackets (0);
124 
126 { AJAAutoLock locker(&gGlobalLock);
128 }
129 
131 { AJAAutoLock locker(&gGlobalLock);
133 }
134 
136 { AJAAutoLock locker(&gGlobalLock);
138 }
139 
140 inline void AJAAncillaryList::SetIncludeZeroLengthPackets (const bool inInclude)
141 { AJAAutoLock locker(&gGlobalLock);
142  gIncludeZeroLengthPackets = inInclude;
143 }
144 
145 static inline void BumpZeroLengthPacketCount (void)
146 {
148 }
149 
150 
152 
153 
155  : m_ancList (),
156  m_rcvMultiRTP (true), // By default, handle receiving multiple RTP packets
157  m_xmitMultiRTP (false), // By default, transmit single RTP packet
158  m_ignoreCS (false)
159 {
160  Clear();
167 }
168 
169 #if defined(AJA_USE_CPLUSPLUS11)
171  : m_ancList (std::move(inRHS.m_ancList)),
172  m_rcvMultiRTP (inRHS.m_rcvMultiRTP), // By default, handle receiving multiple RTP packets
173  m_xmitMultiRTP (inRHS.m_xmitMultiRTP), // By default, transmit single RTP packet
174  m_ignoreCS (inRHS.m_ignoreCS)
175 {
176  // Reset RHS...
177  inRHS.m_rcvMultiRTP = true;
178  inRHS.m_xmitMultiRTP = false;
179  inRHS.m_ignoreCS = false;
180  // inRHS.m_ancList - already moved/reset
181 }
182 #endif // defined(AJA_USE_CPLUSPLUS11)
183 
184 
186 {
187  Clear();
188 }
189 
190 
192 {
193  if (this != &inRHS)
194  {
195  m_xmitMultiRTP = inRHS.m_xmitMultiRTP;
196  m_rcvMultiRTP = inRHS.m_rcvMultiRTP;
197  m_ignoreCS = inRHS.m_ignoreCS;
198  Clear();
199  for (AJAAncDataListConstIter it(inRHS.m_ancList.begin()); it != inRHS.m_ancList.end(); ++it)
200  if (*it)
201  AddAncillaryData(*it);
202  }
203  return *this;
204 }
205 
206 #if defined(AJA_USE_CPLUSPLUS11)
208 {
209  if (this != &inRHS)
210  {
211  m_xmitMultiRTP = inRHS.m_xmitMultiRTP;
212  inRHS.m_xmitMultiRTP = false;
213 
214  m_rcvMultiRTP = inRHS.m_rcvMultiRTP;
215  inRHS.m_rcvMultiRTP = true;
216 
217  m_ignoreCS = inRHS.m_ignoreCS;
218  inRHS.m_ignoreCS = false;
219 
220  Clear(); // Clear down any packets currently being held in 'this'
221  m_ancList = std::move(inRHS.m_ancList);
222  }
223  return *this;
224 }
225 #endif // defined(AJA_USE_CPLUSPLUS11)
226 
228 {
229  AJAAncillaryData * pAncData(AJA_NULL);
230 
231  if (inIndex < m_ancList.size())
232  {
233 #if defined(AJAANCLISTIMPL_VECTOR)
234  pAncData = m_ancList[inIndex]; // Yay! std::vector has random access.
235 #else
236  AJAAncDataListConstIter it (m_ancList.begin());
237 
238  for (uint32_t i(0); i < inIndex; i++) // Dang, std::list has no random access
239  ++it;
240  pAncData = *it;
241 #endif
242  }
243  return pAncData;
244 }
245 
246 
248 {
249  AJAStatus result = AJA_STATUS_SUCCESS;
250 
251  for (AJAAncDataListConstIter it(m_ancList.begin()); it != m_ancList.end(); ++it)
252  {
253  AJAAncillaryData * pAncData = *it;
254  AJAStatus status = pAncData->ParsePayloadData ();
255 
256  // Parse ALL items (even if one fails), but only return success if ALL succeed...
257  if (AJA_FAILURE (status))
258  result = status;
259  }
260  return result;
261 }
262 
263 
265 {
266  uint32_t count = 0;
267 
268  for (AJAAncDataListConstIter it(m_ancList.begin()); it != m_ancList.end(); ++it)
269  {
270  AJAAncillaryData * pAncData (*it);
271  AJAAncDataType ancType (pAncData->GetAncillaryDataType());
272 
273  if (matchType == ancType)
274  count++;
275  }
276  return count;
277 }
278 
279 
280 AJAAncillaryData * AJAAncillaryList::GetAncillaryDataWithType (const AJAAncDataType matchType, const uint32_t index) const
281 {
282  AJAAncillaryData * pResult (AJA_NULL);
283  uint32_t count = 0;
284 
285  for (AJAAncDataListConstIter it(m_ancList.begin()); it != m_ancList.end(); ++it)
286  {
287  AJAAncillaryData * pAncData (*it);
288  AJAAncDataType ancType (pAncData->GetAncillaryDataType());
289 
290  if (matchType == ancType)
291  {
292  if (index == count)
293  {
294  pResult = pAncData;
295  break;
296  }
297  else
298  count++;
299  }
300  }
301  return pResult;
302 }
303 
304 
305 uint32_t AJAAncillaryList::CountAncillaryDataWithID (const uint8_t DID, const uint8_t SID) const
306 {
307  uint32_t count = 0;
308 
309  for (AJAAncDataListConstIter it(m_ancList.begin()); it != m_ancList.end(); ++it)
310  {
311  AJAAncillaryData * pAncData = *it;
312 
313  if (DID == AJAAncillaryDataWildcard_DID || DID == pAncData->GetDID())
314  {
315  if (SID == AJAAncillaryDataWildcard_SID || SID == pAncData->GetSID())
316  count++;
317  }
318  }
319  return count;
320 }
321 
322 
323 AJAAncillaryData * AJAAncillaryList::GetAncillaryDataWithID (const uint8_t inDID, const uint8_t inSID, const uint32_t index) const
324 {
325  AJAAncillaryData * pResult (AJA_NULL);
326  uint32_t count(0);
327 
328  for (AJAAncDataListConstIter it(m_ancList.begin()); it != m_ancList.end(); ++it)
329  {
330  if (inDID == AJAAncillaryDataWildcard_DID || inDID == (*it)->GetDID())
331  {
332  if (inSID == AJAAncillaryDataWildcard_SID || inSID == (*it)->GetSID())
333  {
334  if (index == count)
335  {
336  pResult = *it;
337  break;
338  }
339  count++;
340  }
341  }
342  }
343  return pResult;
344 }
345 
347 {
348  AJAAncPktDIDSIDSet result;
349  for (AJAAncDataListConstIter it(m_ancList.begin()); it != m_ancList.end(); ++it)
350  {
351  const uint16_t pktDIDSID(ToAJAAncPktDIDSID((*it)->GetDID(), (*it)->GetSID()));
352  if (result.find(pktDIDSID) == result.end())
353  result.insert(pktDIDSID);
354  }
355  return result;
356 }
357 
358 
360 {
361  if (&inPackets == this)
362  return AJA_STATUS_BAD_PARAM; // Cannot append from same list!
363  for (AJAAncDataListConstIter it(inPackets.m_ancList.begin()); it != inPackets.m_ancList.end(); ++it)
364  {
365  const AJAAncillaryData * pSrcPkt (*it);
366  if (!pSrcPkt)
367  return AJA_STATUS_FAIL;
368  AJAAncillaryData * pNewPkt (pSrcPkt->Clone());
369  if (!pNewPkt)
370  return AJA_STATUS_FAIL;
371  m_ancList.push_back(pNewPkt);
372  }
373  return AJA_STATUS_SUCCESS;
374 }
375 
376 
378 {
379  if (!pInAncData)
380  return AJA_STATUS_NULL;
381 
382  // Note: this makes a clone of the incoming AJAAncillaryData object and
383  // saves it in the List. The caller is responsible for deleting the original,
384  // and the List owns the clone.
385  const bool wasEmpty (m_ancList.empty());
386  AJAAncillaryData * pData (pInAncData->Clone());
387  if (!pData)
388  return AJA_STATUS_FAIL;
389 
390  // add it to the list
391  if (pData)
392  m_ancList.push_back(pData);
393 
394  LOGMYDEBUG(DEC(m_ancList.size()) << " packet(s) stored" << (wasEmpty ? " from" : " after appending") << " packet " << pData->AsString(32));
395  return AJA_STATUS_SUCCESS;
396 }
397 
398 
400 {
401  uint32_t numDeleted (0);
402  const uint32_t oldSize (uint32_t(m_ancList.size()));
403  for (AJAAncDataListConstIter it (m_ancList.begin()); it != m_ancList.end(); ++it)
404  {
405  AJAAncillaryData * pAncData(*it);
406  if (pAncData)
407  {
408  delete pAncData;
409  numDeleted++;
410  }
411  }
412 
413  m_ancList.clear();
414  if (oldSize || numDeleted)
415  LOGMYDEBUG(numDeleted << " packet(s) deleted -- list emptied");
416  return AJA_STATUS_SUCCESS;
417 }
418 
419 
421 {
422  if (!pAncData)
423  return AJA_STATUS_NULL;
424 
425 #if defined(AJAANCLISTIMPL_VECTOR)
427  for (it = m_ancList.begin(); it != m_ancList.end(); ++it)
428  if (*it == pAncData)
429  break;
430  if (it == m_ancList.end())
431  {LOGMYERROR("failed to remove packet " << pAncData->AsString(32)); return AJA_STATUS_NOT_FOUND;}
432  m_ancList.erase(it);
433 #else
434  m_ancList.remove(pAncData); // note: there's no feedback as to whether one or more elements existed or not
435  // note: pAncData is NOT deleted!
436 #endif
437  LOGMYDEBUG(DEC(m_ancList.size()) << " packet(s) remain after removing packet " << pAncData->AsString(32));
438  return AJA_STATUS_SUCCESS;
439 }
440 
441 
443 {
444  if (!pAncData)
445  return AJA_STATUS_NULL;
446 
447  AJAStatus status (RemoveAncillaryData(pAncData));
448  if (AJA_SUCCESS(status))
449  delete pAncData;
450  return status;
451 }
452 
453 
454 // Sort Predicates
455 
456 static bool SortByDID (AJAAncillaryData * lhs, AJAAncillaryData * rhs)
457 {
458  return lhs->GetDID() < rhs->GetDID();
459 }
460 
461 
462 static bool SortBySID (AJAAncillaryData * lhs, AJAAncillaryData * rhs)
463 {
464  return lhs->GetSID() < rhs->GetSID();
465 }
466 
468 {
469  const AJAAncDataLoc & locLHS (lhs->GetDataLocation());
470  const AJAAncDataLoc & locRHS (rhs->GetDataLocation());
471  return locLHS < locRHS;
472 }
473 
474 
475 // Sort Methods
476 
478 {
479 #if defined(AJAANCLISTIMPL_VECTOR)
480  std::sort(m_ancList.begin(), m_ancList.end(), SortByDID);
481 #else
482  m_ancList.sort (SortByDID);
483 #endif
484  return AJA_STATUS_SUCCESS;
485 }
486 
487 
489 {
490 #if defined(AJAANCLISTIMPL_VECTOR)
491  std::sort(m_ancList.begin(), m_ancList.end(), SortBySID);
492 #else
493  m_ancList.sort (SortBySID);
494 #endif
495  return AJA_STATUS_SUCCESS;
496 }
497 
499 {
500 #if defined(AJAANCLISTIMPL_VECTOR)
501  std::sort(m_ancList.begin(), m_ancList.end(), SortByLocation);
502 #else
503  m_ancList.sort(SortByLocation);
504 #endif
505  return AJA_STATUS_SUCCESS;
506 }
507 
508 
509 AJAStatus AJAAncillaryList::Compare (const AJAAncillaryList & inCompareList, const bool inIgnoreLocation, const bool inIgnoreChecksum) const
510 {
511  if (inCompareList.CountAncillaryData() != CountAncillaryData())
512  return AJA_STATUS_FAIL;
513  for (uint32_t ndx (0); ndx < CountAncillaryData(); ndx++)
514  {
515  AJAAncillaryData * pPktA (inCompareList.GetAncillaryDataAtIndex(ndx));
517  if (AJA_FAILURE(pPktA->Compare(*pPktB, inIgnoreLocation, inIgnoreChecksum)))
518  return AJA_STATUS_FAIL;
519  } // for each packet
520  return AJA_STATUS_SUCCESS;
521 }
522 
523 
524 string AJAAncillaryList::CompareWithInfo (const AJAAncillaryList & inCompareList, const bool inIgnoreLocation, const bool inIgnoreChecksum) const
525 {
526  ostringstream oss;
527  if (inCompareList.CountAncillaryData() != CountAncillaryData())
528  { oss << "Packet count mismatch: " << DEC(CountAncillaryData()) << " vs " << DEC(inCompareList.CountAncillaryData());
529  return oss.str();
530  }
531 
532  for (uint32_t ndx (0); ndx < CountAncillaryData(); ndx++)
533  {
534  AJAAncillaryData * pPktRHS (inCompareList.GetAncillaryDataAtIndex(ndx));
536  const string info (pPkt->CompareWithInfo(*pPktRHS, inIgnoreLocation, inIgnoreChecksum));
537  if (!info.empty())
538  {
539  oss << "Pkt " << DEC(ndx+1) << " of " << DEC(CountAncillaryData()) << ": " << pPkt->AsString() << " != " << pPktRHS->AsString() << ": " << info;
540  return oss.str();
541  }
542  } // for each packet
543  return string();
544 }
545 
546 
547 bool AJAAncillaryList::CompareWithInfo (vector<string> & outDiffInfo, const AJAAncillaryList & inCompareList, const bool inIgnoreLocation, const bool inIgnoreChecksum) const
548 {
549  outDiffInfo.clear();
550  if (inCompareList.CountAncillaryData() != CountAncillaryData())
551  {
552  ostringstream oss;
553  oss << "Packet count mismatch: " << DEC(CountAncillaryData()) << " vs " << DEC(inCompareList.CountAncillaryData());
554  outDiffInfo.push_back(oss.str());
555  return false; // Miscompared
556  }
557 
558  for (uint32_t ndx(0); ndx < CountAncillaryData(); ndx++)
559  {
560  AJAAncillaryData * pPktRHS (inCompareList.GetAncillaryDataAtIndex(ndx));
562  const string info (pPkt->CompareWithInfo(*pPktRHS, inIgnoreLocation, inIgnoreChecksum));
563  if (!info.empty())
564  {
565  ostringstream oss;
566  oss << "Pkt " << DEC(ndx+1) << " of " << DEC(CountAncillaryData()) << ":" << endl
567  << "LHS " << pPkt->AsString(250) << endl
568  << "RHS " << pPktRHS->AsString(250) << endl
569  << info;
570  outDiffInfo.push_back(oss.str());
571  }
572  } // for each packet
573  return outDiffInfo.empty(); // equal if empty list
574 }
575 
576 
580 
581 // Parse a stream of "raw" ancillary data as collected by an AJAAncExtractorWidget.
582 // Break the stream into separate AJAAncillaryData objects and add them to the list.
583 //
584 AJAStatus AJAAncillaryList::AddReceivedAncillaryData (const NTV2Buffer & inReceivedData, const uint32_t inFrameNum)
585 {
586  AJAStatus status (AJA_STATUS_SUCCESS);
587  if (!inReceivedData)
588  return AJA_STATUS_NULL;
589 
590  AJAAncillaryDataList rawPkts; // Accumulate "analog/raw" packets separately
591  AJAAncillaryData newAncData; // Use this as an uninitialized template
593  int32_t remainingSize (int32_t(inReceivedData.GetByteCount()));
594  const uint8_t * pInputData (inReceivedData);
595  bool bMoreData (true);
596 
597  while (bMoreData)
598  {
599  bool bInsertNew (false); // We'll set this 'true' if/when we find a new Anc packet to insert
600  AJAAncDataType newAncType (AJAAncDataType_Unknown); // We'll set this to the proper type once we know it
601  uint32_t packetSize (0); // This is where the AncillaryData object returns the number of bytes that were "consumed" from the input stream
602 
603  // Reset the AncData object, then load itself from the next GUMP packet...
604  newAncData.Clear();
605  status = newAncData.InitWithReceivedData (pInputData, size_t(remainingSize), defaultLoc, packetSize);
606  if (AJA_FAILURE(status))
607  {
608  // TODO: Someday, let's try to recover and process subsequent packets.
609  break; // NOTE: For now, bail on errors in the GUMP stream
610  }
611  else if (packetSize == 0)
612  break; // Nothing to do
613 
614  // Determine what type of anc data we have, and create an object of the appropriate class...
615  if (newAncData.IsDigital())
616  {
617  // Digital anc packets are fairly easy to categorize: you just have to look at their DID/SID.
618  // Also, they are (by definition) independent packets which become independent AJAAncillaryData objects.
619  newAncType = AJAAncillaryDataFactory::GuessAncillaryDataType(&newAncData);
620  bInsertNew = true; // Add it to the list
621  } // digital anc data
622  else if (newAncData.IsRaw())
623  { // "Analog" packets are trickier...
624  // 1) Digitized analog lines are broken into multiple packets by the hardware,
625  // which need to be recombined into a single AJAAncillaryData object.
626  // 2) It is harder to classify the data type, since there is no single easy-to-read
627  // ID. Instead, we rely on the user to tell us what lines are expected to contain
628  // what kind of data (e.g. "expect line 21 to carry 608 captioning...").
629 
630  // This function used to assume that analog packets always were in succession in the buffer.
631  // This isn't true, however, if packet filtering is disabled. Audio packets can be interspersed
632  // between successive analog packets. We now accumulate analog packets separately in "rawPkts",
633  // then add them all to my "m_ancList" member last.
634 
635  // Look for a pkt in "rawPkts" that has the same location...
636  const uint64_t desiredLocation (newAncData.GetDataLocation().OrdinalValue());
637  AJAAncillaryData * pContinuationPkt (AJA_NULL);
638  for (AJAAncDataListConstIter pRaw(rawPkts.begin()); pRaw != rawPkts.end(); ++pRaw)
639  if ((*pRaw)->GetDataLocation().OrdinalValue() == desiredLocation)
640  { // Found one!
641  // "newAncData" must be a continuation of the "pRaw" pkt.
642  // Simply append the new payload data to it...
643  pContinuationPkt = *pRaw;
644  pContinuationPkt->AppendPayload(newAncData);
645  break;
646  }
647 
648  if (!pContinuationPkt)
649  { // If this is NOT a "continuation" packet, then this is a new analog packet.
650  // See if the user has specified an expected Anc data type that matches the
651  // location of the new data...
652  newAncType = GetAnalogAncillaryDataType(newAncData);
653  bInsertNew = true; // Create the new raw pkt, and add it to "rawPkts" queue (below)
654  }
655  } // analog anc data
656 // else
657 // Anc Coding Unknown???? (ignore it)
658 
659  if (bInsertNew)
660  {
661  // Create an AJAAncillaryData object of the appropriate type, and init it with our raw data...
662  AJAAncillaryData * pData (AJAAncillaryDataFactory::Create (newAncType, &newAncData));
663  if (pData)
664  {
666  if (IsIncludingZeroLengthPackets() || pData->GetDC())
667  {
668  try {
669  if (pData->IsRaw())
670  rawPkts.push_back(pData); // New analog pkts go onto my rawPkts queue
671  else
672  m_ancList.push_back(pData); // New digital pkts are immediately appended to my list
673  } catch(...) {status = AJA_STATUS_FAIL;}
674  }
676  if (inFrameNum && !pData->GetFrameID())
677  pData->SetFrameID(inFrameNum);
678  }
679  else
680  status = AJA_STATUS_FAIL;
681  }
682 
683  remainingSize -= packetSize; // Decrease the remaining data size by the amount we just "consumed"
684  pInputData += packetSize; // Advance the input data pointer by the same amount
685  if (remainingSize <= 0) // All of the input data consumed?
686  bMoreData = false;
687  } // while (bMoreData)
688 
689  if (AJA_SUCCESS(status) && !rawPkts.empty())
690  { // Append accumulated analog/raw packets...
691  while (AJA_SUCCESS(status) && !rawPkts.empty())
692  {
693  try {
694  m_ancList.push_back(rawPkts.back());
695  } catch(...) {status = AJA_STATUS_FAIL;}
696  rawPkts.pop_back();
697  }
698  if (AJA_SUCCESS(status))
699  status = SortListByLocation(); // Re-sort by location
700  }
701 
702  return status;
703 
704 } // AddReceivedAncillaryData
705 
706 // Parse a stream of "raw" ancillary data as collected by an HDMI Aux Extractor.
707 // Break the stream into separate AJAAncillaryData objects and add them to the list.
708 //
710  const uint32_t inFrameNum)
711 {
712  AJAStatus status (AJA_STATUS_SUCCESS);
713  const uint8_t * pRcvData = inReceivedData;
714  const uint32_t dataSize = inReceivedData.GetByteCount();
715  if (!pRcvData || !dataSize)
716  return AJA_STATUS_NULL;
717 
718  // Use this as an uninitialized template...
719  AJAAncillaryData newAncData;
720  int32_t remainingSize (int32_t(dataSize + 0));
721  const uint8_t * pInputData (pRcvData);
722  bool bMoreData (true);
723 
724  while (bMoreData)
725  {
726  uint32_t packetSize (0); // This is where the AncillaryData object returns the number of bytes that were "consumed" from the input stream
727  status = newAncData.InitAuxWithReceivedData (pInputData, size_t(remainingSize), packetSize);
728  if (AJA_FAILURE(status))
729  {
730  // TODO: Someday, try to recover and process subsequent packets.
731  break; // NOTE: For now, bail on errors in the stream
732  }
733  else if (packetSize == 0)
734  break; // Nothing to do
735 
736  // Create an AJAAuxiliaryData object of the appropriate type, and init it with our raw data...
738  if (pData)
739  {
741  if (IsIncludingZeroLengthPackets() || pData->GetDC())
742  {
743  try {m_ancList.push_back(pData);} // Append to my list
744  catch(...) {status = AJA_STATUS_FAIL;}
745  }
747  if (inFrameNum && !pData->GetFrameID())
748  pData->SetFrameID(inFrameNum);
749  }
750  else
751  status = AJA_STATUS_FAIL;
752 
753 
754  remainingSize -= packetSize; // Decrease the remaining data size by the amount we just "consumed"
755  pInputData += packetSize; // Advance the input data pointer by the same amount
756  if (remainingSize <= 0) // All of the input data consumed?
757  bMoreData = false;
758  } // while (bMoreData)
759 
760  return status;
761 
762 } // AddReceivedAncillaryData
763 
764 // Parse a "raw" RTP packet received from hardware (ingest) in network byte order into separate
765 // AJAAncillaryData objects and append them to me. 'inReceivedData' includes the RTP header.
767 {
768  AJAStatus status (AJA_STATUS_SUCCESS);
769  if (inReceivedData.empty())
770  {LOGMYWARN("Empty RTP data vector"); return AJA_STATUS_SUCCESS;}
771 
772 LOGMYDEBUG(::ULWordSequenceToStringBE(inReceivedData) << " (BigEndian)"); // ByteSwap em to make em look right
773 
774  // Crack open the RTP packet header...
775  AJARTPAncPayloadHeader RTPheader;
776  if (!RTPheader.ReadFromULWordVector(inReceivedData))
777  {LOGMYERROR("AJARTPAncPayloadHeader::ReadULWordVector failed, " << DEC(4*inReceivedData.size()) << " header bytes"); return AJA_STATUS_FAIL;}
778  if (RTPheader.IsNULL())
779  {LOGMYWARN("No anc packets added: NULL RTP header: " << RTPheader); return AJA_STATUS_SUCCESS;} // Not an error
780  if (!RTPheader.IsValid())
781  {LOGMYWARN("RTP header invalid: " << RTPheader); return AJA_STATUS_FAIL;}
782 
783  const size_t predictedPayloadSize (RTPheader.GetPayloadLength() / sizeof(uint32_t)); // Payload length (excluding RTP header)
784  const size_t actualPayloadSize (inReceivedData.size() - AJARTPAncPayloadHeader::GetHeaderWordCount());
785  const uint32_t numPackets (RTPheader.GetAncPacketCount());
786  uint32_t pktsAdded (0);
787 
788  // Sanity check the RTP header against inReceivedData...
789  if (actualPayloadSize < predictedPayloadSize)
790  {LOGMYERROR("Expected " << DEC(predictedPayloadSize) << ", but only given " << DEC(actualPayloadSize) << " U32s: " << RTPheader); return AJA_STATUS_BADBUFFERCOUNT;}
791  if (!numPackets)
792  {LOGMYWARN("No Anc packets to append: " << RTPheader); return AJA_STATUS_SUCCESS;}
793  if (!actualPayloadSize)
794  {LOGMYWARN("No payload data yet non-zero packet count: " << RTPheader); return AJA_STATUS_FAIL;}
795 
796 LOGMYDEBUG(RTPheader);
797 
798  // Parse each anc pkt in the RTP pkt...
799  uint16_t u32Ndx (5); // First Anc packet starts at ULWord[5]
800  unsigned pktNum (0);
801  for (; pktNum < numPackets && AJA_SUCCESS(status); pktNum++)
802  {
803  AJAAncillaryData tempPkt;
804  status = tempPkt.InitWithReceivedData(inReceivedData, u32Ndx, IgnoreChecksumErrors());
805  if (AJA_FAILURE(status))
806  continue;
807 
809  AJAAncillaryData * pNewPkt (AJAAncillaryDataFactory::Create (newAncType, tempPkt));
810  if (!pNewPkt)
811  {status = AJA_STATUS_NULL; continue;}
812 
813  pNewPkt->SetBufferFormat(AJAAncBufferFormat_RTP); // Originated in RTP packet
814  pNewPkt->SetFrameID(RTPheader.GetTimeStamp()); // TimeStamp it using RTP timestamp
815  if (IsIncludingZeroLengthPackets() || pNewPkt->GetDC())
816  {
817  try {m_ancList.push_back(pNewPkt); pktsAdded++;} // Append to my list
818  catch(...) {status = AJA_STATUS_FAIL;}
819  }
821  } // for each anc packet
822 
823  if (AJA_FAILURE(status))
824  LOGMYERROR(::AJAStatusToString(status) << ": Failed at pkt[" << DEC(pktNum) << "] of " << DEC(numPackets));
825  if (CountAncillaryData() < numPackets)
826  {LOGMYWARN(DEC(pktsAdded) << " of " << DEC(numPackets) << " anc pkt(s) decoded from RTP pkt");}
827  else
828  LOGMYINFO(DEC(numPackets) << " pkts added from RTP pkt: " << *this);
829  return status;
830 } // AddReceivedAncillaryData
831 
832 
834  const UWordSequence & inPacketWords,
838  0))
839 {
840  AJAStatus status (AJA_STATUS_SUCCESS);
841 
842  if (inPacketWords.size () < 7)
843  return AJA_STATUS_RANGE;
844 // NOTE: Tough call. Decided not to validate the AJAAncDataLoc here:
845 // if (!inLoc.IsValid())
846 // return AJA_STATUS_BAD_PARAM;
847 
848  // Use this as an uninitialized template...
849  UWordSequenceConstIter iter(inPacketWords.begin());
850 
851  // Anc packet must start with 0x000 0x3FF 0x3FF sequence...
852  if (*iter != 0x0000)
853  return AJA_STATUS_FAIL;
854  ++iter;
855  if (*iter != 0x03FF)
856  return AJA_STATUS_FAIL;
857  ++iter;
858  if (*iter != 0x03FF)
859  return AJA_STATUS_FAIL;
860  ++iter; // Now pointing at DID
861 
862  outGumpPkt.reserve (outGumpPkt.size() + inPacketWords.size()); // Expand outGumpPkt's capacity in one step
863  const UByteSequence::size_type dataByte1Ndx (outGumpPkt.size()+1); // Index of byte[1] in outgoing Gump packet
864  outGumpPkt.push_back(0xFF); // [0] First byte always 0xFF
865  outGumpPkt.push_back(0x80); // [1] Location data byte 1: "location valid" bit always set
866  outGumpPkt[dataByte1Ndx] |= (inLoc.GetLineNumber() >> 7) & 0x0F; // [1] Location data byte 1: LS 4 bits == MS 4 bits of 11-bit line number
867  if (inLoc.IsLumaChannel())
868  outGumpPkt[dataByte1Ndx] |= 0x20; // [1] Location data byte 1: set Y/C bit for Y/luma channel
869  if (inLoc.IsHanc())
870  outGumpPkt[dataByte1Ndx] |= 0x10; // [1] Location data byte 1: set H/V bit for HANC
871  outGumpPkt.push_back (inLoc.GetLineNumber() & 0x7F); // [2] Location data byte 2: MSB reserved; LS 7 bits == LS 7 bits of 11-bit line number
872 
873  while (iter != inPacketWords.end())
874  {
875  outGumpPkt.push_back(*iter & 0xFF); // Mask off upper byte
876  ++iter;
877  }
878  return status;
879 }
880 
881 
882 AJAStatus AJAAncillaryList::AddVANCData (const UWordSequence & inPacketWords, const AJAAncDataLoc & inLocation, const uint32_t inFrameNum)
883 {
884  UByteSequence gumpPacketData;
885  AJAStatus status (AppendUWordPacketToGump (gumpPacketData, inPacketWords, inLocation));
886  if (AJA_FAILURE(status))
887  return status;
888 
890  AJAAncillaryData * pData (AJA_NULL);
891  {
892  AJAAncillaryData pkt;
893  status = pkt.InitWithReceivedData (gumpPacketData, inLocation);
894  if (AJA_FAILURE(status))
895  return status;
897 
899  pData = AJAAncillaryDataFactory::Create(newAncType, pkt);
900  if (!pData)
901  return AJA_STATUS_FAIL;
902  }
903 
904  if (IsIncludingZeroLengthPackets() || pData->GetDC())
905  {
906  try {m_ancList.push_back(pData);} // Append to my list, I now own the instance
907  catch(...) {delete pData; return AJA_STATUS_FAIL;}
908 
909  if (inFrameNum && pData->GetDID())
910  pData->SetFrameID(inFrameNum);
911  }
912  else
913  {
915  delete pData; // Don't leak zero-length packets
916  }
917  return AJA_STATUS_SUCCESS;
918 
919 } // AddVANCData
920 
921 
923  const NTV2FormatDesc & inFD,
924  AJAAncillaryList & outPkts,
925  const uint32_t inFrameNum)
926 {
927  outPkts.Clear();
928  if (inFB.IsNULL())
929  {
930  LOGMYERROR("AJA_STATUS_NULL: NULL frame buffer pointer");
931  return AJA_STATUS_NULL;
932  }
933  if (!inFD.IsValid())
934  {
935  LOGMYERROR("AJA_STATUS_BAD_PARAM: bad NTV2FormatDescriptor");
936  return AJA_STATUS_BAD_PARAM;
937  }
938  if (!inFD.IsVANC())
939  {
940  LOGMYERROR("AJA_STATUS_BAD_PARAM: format descriptor has no VANC lines");
941  return AJA_STATUS_BAD_PARAM;
942  }
943 
944  const ULWord vancBytes (inFD.GetTotalRasterBytes() - inFD.GetVisibleRasterBytes());
945  const NTV2PixelFormat fbf (inFD.GetPixelFormat());
946  const bool isSD (NTV2_IS_SD_STANDARD(inFD.GetVideoStandard()));
947  if (inFB.GetByteCount() < vancBytes)
948  {
949  LOGMYERROR("AJA_STATUS_FAIL: " << inFB.GetByteCount() << "-byte frame buffer smaller than " << vancBytes << "-byte VANC region");
950  return AJA_STATUS_FAIL;
951  }
952  if (fbf != NTV2_FBF_10BIT_YCBCR && fbf != NTV2_FBF_8BIT_YCBCR)
953  {
954  LOGMYERROR("AJA_STATUS_UNSUPPORTED: frame buffer format " << ::NTV2FrameBufferFormatToString(fbf) << " not '2vuy' nor 'v210'");
955  return AJA_STATUS_UNSUPPORTED; // Only 'v210' and '2vuy' currently supported
956  }
957 
958  for (ULWord lineOffset (0); lineOffset < inFD.GetFirstActiveLine(); lineOffset++)
959  {
960  UWordSequence uwords;
961  bool isF2 (false);
962  ULWord smpteLineNum (0);
963  unsigned ndx (0);
964  const AJAAncDataLink defaultLink (AJAAncDataLink_A); // This is most common
965 
966  inFD.GetSMPTELineNumber (lineOffset, smpteLineNum, isF2);
967  if (fbf == NTV2_FBF_10BIT_YCBCR)
968  ::UnpackLine_10BitYUVtoUWordSequence (inFD.GetRowAddress(inFB.GetHostAddress(0), lineOffset), inFD, uwords);
969  else if (isSD)
971  uwords, inFD.GetRasterWidth());
972  else
974  uwords, inFD.GetRasterWidth());
975  if (isSD)
976  {
978  UWordSequence ycHOffsets;
979  AJAAncDataLoc loc (defaultLink, AJAAncDataChannel_Both, AJAAncDataSpace_VANC, uint16_t(smpteLineNum));
980 
982  NTV2_ASSERT(ycPackets.size() == ycHOffsets.size());
983 
984  for (AJAAncillaryData::U16Packets::const_iterator it(ycPackets.begin()); it != ycPackets.end(); ++it, ndx++)
985  outPkts.AddVANCData (*it, loc.SetHorizontalOffset(ycHOffsets[ndx]), inFrameNum);
986  }
987  else
988  {
989  AJAAncillaryData::U16Packets yPackets, cPackets;
990  UWordSequence yHOffsets, cHOffsets;
991  AJAAncDataLoc yLoc (defaultLink, AJAAncDataChannel_Y, AJAAncDataSpace_VANC, uint16_t(smpteLineNum));
992  AJAAncDataLoc cLoc (defaultLink, AJAAncDataChannel_C, AJAAncDataSpace_VANC, uint16_t(smpteLineNum));
993  //cerr << endl << "SetFromVANCData: +" << DEC0N(lineOffset,2) << ": "; inFD.PrintSMPTELineNumber(cerr, lineOffset); cerr << ":" << endl << uwords << endl;
996  NTV2_ASSERT(yPackets.size() == yHOffsets.size());
997  NTV2_ASSERT(cPackets.size() == cHOffsets.size());
998 
999  unsigned ndxx(0);
1000  for (AJAAncillaryData::U16Packets::const_iterator it(yPackets.begin()); it != yPackets.end(); ++it, ndxx++)
1001  outPkts.AddVANCData (*it, yLoc.SetHorizontalOffset(yHOffsets[ndxx]), inFrameNum);
1002 
1003  ndxx = 0;
1004  for (AJAAncillaryData::U16Packets::const_iterator it(cPackets.begin()); it != cPackets.end(); ++it, ndxx++)
1005  outPkts.AddVANCData (*it, cLoc.SetHorizontalOffset(cHOffsets[ndxx]), inFrameNum);
1006  }
1007  } // for each VANC line
1008  LOGMYDEBUG("returning " << outPkts);
1009  return AJA_STATUS_SUCCESS;
1010 }
1011 
1012 // STATIC
1014  AJAAncillaryList & outPackets,
1015  const uint32_t inFrameNum)
1016 {
1017  uint32_t RTPPacketCount (0); // Number of packets encountered
1018  const uint32_t origPktCount (outPackets.CountAncillaryData());
1019  AJAStatus result (AJA_STATUS_SUCCESS);
1020 
1021  // Try GUMP first...
1022  if (BufferHasGUMPData(inAncBuffer))
1023  { // GUMP GUMP GUMP GUMP GUMP GUMP GUMP GUMP GUMP GUMP GUMP GUMP GUMP GUMP GUMP GUMP GUMP GUMP
1024  result = outPackets.AddReceivedAncillaryData (inAncBuffer, inFrameNum);
1025  if (result == AJA_STATUS_NULL)
1026  result = AJA_STATUS_SUCCESS; // A NULL/empty buffer is not an error
1027  } // if GUMP
1028  else
1029  {
1030  // RTP RTP RTP RTP RTP RTP RTP RTP RTP RTP RTP RTP RTP RTP RTP RTP RTP RTP
1031  NTV2Buffer ancBuffer (inAncBuffer.GetHostPointer(), inAncBuffer.GetByteCount()); // Don't copy
1032  size_t ULWordCount (0); // Size of current RTP packet, including RTP header, in 32-bit words
1033  size_t ULWordOffset (0); // Offset to start of current RTP packet, in 32-bit words
1034  unsigned retries (0); // Retry count
1035  const unsigned MAX_RETRIES (4); // Max number of U32s past the end of an RTP packet to look for another
1036 
1037  while (ancBuffer && retries++ < MAX_RETRIES)
1038  {
1040  {
1041  ULWordSequence U32s;
1042  AJARTPAncPayloadHeader rtpHeader;
1043 
1044  ++RTPPacketCount; // Increment our packet tally
1045 
1046  // Read the RTP packet header to discover the RTP packet's true length...
1047  if (!rtpHeader.ReadFromBuffer(ancBuffer))
1048  {
1049  RCVWARN("On RTP pkt " << DEC(RTPPacketCount) << ", RTP hdr ReadFromBuffer failed at: " << ancBuffer.AsString(40));
1050  break;
1051  }
1052 
1053  ULWordCount = rtpHeader.GetPayloadLength() / sizeof(uint32_t) // payload size
1054  + AJARTPAncPayloadHeader::GetHeaderWordCount(); // plus RTP header size
1055 
1056  // Read ULWordCount x U32s from ancBuffer...
1057  if (!ancBuffer.GetU32s (U32s, /*U32Offset=*/0, /*maxU32sToGet=*/ULWordCount))
1058  {
1059  RCVFAIL("On RTP pkt " << DEC(RTPPacketCount) << ", GetU32s(" << DEC(ULWordCount) << ") at: " << ancBuffer.AsString(40));
1060  return AJA_STATUS_BADBUFFERSIZE; // Ran off the end?
1061  }
1062 
1063  retries = 0; // Reset our retry counter when we get a good header
1064 
1065  // Process the full RTP packet U32s...
1066  result = outPackets.AddReceivedAncillaryData(U32s);
1067  if (AJA_FAILURE(result))
1068  break; // Done -- failed!
1069 
1070  if (!outPackets.AllowMultiRTPReceive())
1071  break; // Only one RTP packet allowed -- done -- success!
1072  } //
1073  else
1074  ULWordCount = 1; // No RTP header found -- move ahead 1 x U32
1075 
1076  // Move "ancBuffer" forward inside "inAncBuffer" to check for another RTP packet...
1077  ULWordOffset += ULWordCount;
1078  ancBuffer.Set (inAncBuffer.GetHostAddress(ULWord(ULWordOffset * sizeof(uint32_t))), // Increment startAddress
1079  inAncBuffer.GetByteCount() - ULWordOffset * sizeof(uint32_t)); // Decrement byteCount
1080  RCVDBG("Moved buffer " << inAncBuffer << " forward by " << DEC(ULWordCount) << " U32s: " << ancBuffer.AsString(20));
1081  } // loop til no more RTP packets found
1082  } // else RTP
1083 
1084  const uint32_t pktsAdded (outPackets.CountAncillaryData() - origPktCount);
1085  if (AJA_SUCCESS(result))
1086  {LOGMYDEBUG("Success: " << DEC(pktsAdded) << " pkts added");}
1087  else
1088  LOGMYERROR(AJAStatusToString(result) << ": " << DEC(pktsAdded) << " pkts added");
1089  return result;
1090 
1091 } // AddFromDeviceAncBuffer
1092 
1093 // STATIC
1095  AJAAncillaryList & outPackets,
1096  const uint32_t inFrameNum)
1097 {
1098  //uint32_t RTPPacketCount (0); // Number of packets encountered
1099  const uint32_t origPktCount (outPackets.CountAncillaryData());
1100  AJAStatus result (AJA_STATUS_SUCCESS);
1101 
1102 
1103  result = outPackets.AddReceivedAuxiliaryData (inAuxBuffer, inFrameNum);
1104  if (result == AJA_STATUS_NULL)
1105  result = AJA_STATUS_SUCCESS; // A NULL/empty buffer is not an error
1106 
1107  const uint32_t pktsAdded (outPackets.CountAncillaryData() - origPktCount);
1108  if (AJA_SUCCESS(result))
1109  {LOGMYDEBUG("Success: " << DEC(pktsAdded) << " pkts added");}
1110  else
1111  LOGMYERROR(AJAStatusToString(result) << ": " << DEC(pktsAdded) << " pkts added");
1112  return result;
1113 
1114 } // AddFromDeviceAuxBuffer
1115 
1116 
1117 // STATIC
1119  const NTV2Buffer & inF2AncBuffer,
1120  AJAAncillaryList & outPackets,
1121  const uint32_t inFrameNum) // STATIC
1122 {
1123  outPackets.Clear();
1124  AJAStatus resultF1(AJA_STATUS_SUCCESS), resultF2(AJA_STATUS_SUCCESS);
1125  resultF1 = AddFromDeviceAncBuffer(inF1AncBuffer, outPackets, inFrameNum);
1126  if (inF2AncBuffer) //Unnecessary to extract from empty buffer, and prevents 0 Packets debug message.
1127  resultF2 = AddFromDeviceAncBuffer(inF2AncBuffer, outPackets, inFrameNum);
1128  if (AJA_FAILURE(resultF1))
1129  return resultF1;
1130  if (AJA_FAILURE(resultF2))
1131  return resultF2;
1132  return AJA_STATUS_SUCCESS;
1133 }
1134 
1136  const NTV2Buffer & inF2AuxBuffer,
1137  AJAAncillaryList & outPackets,
1138  const uint32_t inFrameNum) // STATIC
1139 {
1140  outPackets.Clear();
1141  AJAStatus resultF1,resultF2;
1142  resultF1 = resultF2 = AJA_STATUS_SUCCESS;
1143  resultF1 = AddFromDeviceAuxBuffer(inF1AuxBuffer, outPackets, inFrameNum);
1144  if (inF2AuxBuffer) //Unnecessary to extract from empty buffer, and prevents 0 Packets debug message.
1145  resultF2 = AddFromDeviceAuxBuffer(inF2AuxBuffer, outPackets, inFrameNum);
1146  if (AJA_FAILURE(resultF1))
1147  return resultF1;
1148  if (AJA_FAILURE(resultF2))
1149  return resultF2;
1150  return AJA_STATUS_SUCCESS;
1151 }
1152 
1153 static const size_t MAX_RTP_PKT_LENGTH_BYTES (0x0000FFFF); // 65535 max
1154 static const size_t MAX_RTP_PKT_LENGTH_WORDS ((MAX_RTP_PKT_LENGTH_BYTES+1) / sizeof(uint32_t) - 1); // 16383 max
1155 static const uint32_t MAX_ANC_PKTS_PER_RTP_PKT (0x000000FF); // 255 max
1156 
1157 
1159  AJAAncPktCounts & outF1AncCounts, AJAAncPktCounts & outF2AncCounts,
1160  const bool inIsProgressive, const uint32_t inF2StartLine)
1161 {
1162  AJAStatus result (AJA_STATUS_SUCCESS);
1163  uint32_t actF1PktCnt (0);
1164  uint32_t actF2PktCnt (0);
1165  uint32_t pktNdx (0);
1166  size_t oldPktLengthWords (0);
1167  unsigned countOverflows (0);
1168  size_t overflowWords (0);
1169 
1170  // Reserve space in AJAU32Pkts vectors...
1171  outF1U32Pkts.reserve(CountAncillaryData()); outF1U32Pkts.clear();
1172  outF2U32Pkts.reserve(CountAncillaryData()); outF2U32Pkts.clear();
1173  outF1AncCounts.clear(); outF2AncCounts.clear();
1174 
1175  ULWordSequence F1U32s, F2U32s;
1176  F1U32s.reserve(MAX_RTP_PKT_LENGTH_WORDS);
1177  if (!inIsProgressive)
1178  F2U32s.reserve(MAX_RTP_PKT_LENGTH_WORDS);
1179  F1U32s.clear(); F2U32s.clear();
1180 
1181  // Generate transmit data for each of my packets...
1182  for (pktNdx = 0; pktNdx < CountAncillaryData(); pktNdx++)
1183  {
1184  AJAAncillaryData * pAncData (GetAncillaryDataAtIndex(pktNdx));
1185  if (!pAncData)
1186  return AJA_STATUS_NULL; // Fail
1187 
1188  AJAAncillaryData & pkt (*pAncData);
1189  if (pkt.GetDataCoding() != AJAAncDataCoding_Digital)
1190  {
1191  LOGMYDEBUG("Skipped Pkt " << DEC(pktNdx+1) << " of " << DEC(CountAncillaryData()) << " -- Analog/Raw");
1192  continue; // Skip analog/raw packets
1193  }
1194 
1195  if (inIsProgressive || pkt.GetLocationLineNumber() < inF2StartLine)
1196  {
1197  if (actF1PktCnt >= MAX_ANC_PKTS_PER_RTP_PKT)
1198  {
1199  countOverflows++;
1200  LOGMYDEBUG("Skipped pkt " << DEC(pktNdx+1) << " of " << DEC(CountAncillaryData()) << ", F1 RTP pkt count overflow: " << pkt.AsString(16));
1201  continue;
1202  }
1203  oldPktLengthWords = F1U32s.size();
1204  result = pkt.GenerateTransmitData(F1U32s);
1205  if (AJA_FAILURE(result))
1206  break; // Bail!
1207  if (F1U32s.size() > MAX_RTP_PKT_LENGTH_WORDS)
1208  {
1209  overflowWords += F1U32s.size() - oldPktLengthWords;
1210  LOGMYDEBUG("Skipped pkt " << DEC(pktNdx+1) << " of " << DEC(CountAncillaryData()) << ": F1 RTP pkt length overflow: " << pkt.AsString(16));
1211  while (F1U32s.size() > oldPktLengthWords)
1212  F1U32s.pop_back();
1213  continue;
1214  }
1215  actF1PktCnt++;
1216  if (AllowMultiRTPTransmit())
1217  { // MULTI RTP PKTS
1218  outF1U32Pkts.push_back(F1U32s); // Append it
1219  outF1AncCounts.push_back(1); // One SMPTE Anc packet per RTP packet
1220  XMTDBG("F1 pkt " << DEC(actF1PktCnt) << ": " << ::ULWordSequenceToStringBE(F1U32s) << " (BigEndian)");
1221  F1U32s.clear(); // Start current pkt over
1222  }
1223  }
1224  else
1225  {
1226  if (actF2PktCnt >= MAX_ANC_PKTS_PER_RTP_PKT)
1227  {
1228  countOverflows++;
1229  LOGMYDEBUG("Skipped pkt " << DEC(pktNdx+1) << " of " << DEC(CountAncillaryData()) << ": F2 RTP pkt count overflow: " << pkt.AsString(16));
1230  continue;
1231  }
1232  oldPktLengthWords = F2U32s.size();
1233  result = pkt.GenerateTransmitData(F2U32s);
1234  if (AJA_FAILURE(result))
1235  break; // Bail!
1236  if (AJA_SUCCESS(result) && F2U32s.size() > MAX_RTP_PKT_LENGTH_WORDS)
1237  {
1238  overflowWords += F2U32s.size() - oldPktLengthWords;
1239  LOGMYDEBUG("Skipped pkt " << DEC(pktNdx+1) << " of " << DEC(CountAncillaryData()) << ": F2 RTP pkt length overflow: " << pkt.AsString(16));
1240  while (F2U32s.size() > oldPktLengthWords)
1241  F2U32s.pop_back();
1242  continue;
1243  }
1244  actF2PktCnt++;
1245  if (AllowMultiRTPTransmit())
1246  { // MULTI RTP PKTS
1247  outF2U32Pkts.push_back(F2U32s); // Append it
1248  outF2AncCounts.push_back(1); // One SMPTE Anc packet per RTP packet
1249  XMTDBG("F2 pkt " << DEC(actF2PktCnt) << ": " << ::ULWordSequenceToStringBE(F2U32s) << " (BigEndian)");
1250  F2U32s.clear(); // Start current pkt over
1251  }
1252  }
1253  } // for each SMPTE Anc packet
1254 
1255  if (AJA_FAILURE(result))
1256  {LOGMYERROR(::AJAStatusToString(result) << ": Pkt " << DEC(pktNdx+1) << " of " << DEC(CountAncillaryData()) << " failed in GenerateTransmitData: " << ::AJAStatusToString(result));}
1257  else if (!AllowMultiRTPTransmit())
1258  { // SINGLE RTP PKT
1259  outF1U32Pkts.push_back(F1U32s); // Append all F1
1260  outF1AncCounts.push_back(uint8_t(actF1PktCnt)); // Total F1 SMPTE Anc packets in this one F1 RTP packet
1261  outF2U32Pkts.push_back(F2U32s); // Append all F2
1262  outF2AncCounts.push_back(uint8_t(actF2PktCnt)); // Total F2 SMPTE Anc packets in this one F2 RTP packet
1263  }
1264  if (overflowWords && countOverflows)
1265  {LOGMYWARN("Overflow: " << DEC(countOverflows) << " pkts skipped, " << DEC(overflowWords) << " U32s dropped");}
1266  else if (overflowWords)
1267  {LOGMYWARN("Data overflow: " << DEC(overflowWords) << " U32s dropped");}
1268  else if (countOverflows)
1269  LOGMYWARN("Packet overflow: " << DEC(countOverflows) << " pkts skipped");
1270  XMTDBG("F1 (Content Only): " << outF1U32Pkts);
1271  XMTDBG("F2 (Content Only): " << outF2U32Pkts);
1272  return result;
1273 } // GetRTPPackets
1274 
1275 
1276 
1280 
1281 
1282 AJAStatus AJAAncillaryList::GetAncillaryDataTransmitSize (const bool bProgressive, const uint32_t f2StartLine, uint32_t & ancSizeF1, uint32_t & ancSizeF2)
1283 {
1284  AJAStatus status (AJA_STATUS_SUCCESS);
1285  uint32_t f1Size (0);
1286  uint32_t f2Size (0);
1287 
1288  for (AJAAncDataListConstIter it(m_ancList.begin()); it != m_ancList.end(); ++it)
1289  {
1290  AJAAncillaryData * pAncData (*it);
1291  uint32_t packetSize (0);
1292  status = pAncData->GetRawPacketSize (packetSize);
1293  if (status != AJA_STATUS_SUCCESS)
1294  break;
1295 
1296  if (bProgressive || pAncData->GetLocationLineNumber () < f2StartLine)
1297  f1Size += packetSize;
1298  else
1299  f2Size += packetSize;
1300  }
1301 
1302  ancSizeF1 = f1Size;
1303  ancSizeF2 = f2Size;
1304  return status;
1305 }
1306 
1307 
1308 AJAStatus AJAAncillaryList::GetAncillaryDataTransmitData (const bool bProgressive, const uint32_t f2StartLine, uint8_t * pF1AncData, const uint32_t inMaxF1Data, uint8_t * pF2AncData, const uint32_t inMaxF2Data)
1309 {
1310  NTV2Buffer F1Buffer(pF1AncData, inMaxF1Data), F2Buffer(pF2AncData, inMaxF2Data);
1311  if (!F1Buffer.IsNULL())
1312  NTV2_ASSERT(F1Buffer.IsProvidedByClient());
1313  if (!F2Buffer.IsNULL())
1314  NTV2_ASSERT(F2Buffer.IsProvidedByClient());
1315  return GetTransmitData(F1Buffer, F2Buffer, bProgressive, f2StartLine);
1316 }
1317 
1318 
1320  const bool inIsProgressive, const uint32_t inF2StartLine)
1321 {
1322  AJAStatus status (AJA_STATUS_SUCCESS);
1323  size_t maxF1Data(F1Buffer), maxF2Data(F2Buffer);
1324  uint8_t *pF1AncData(F1Buffer), *pF2AncData(F2Buffer);
1325 
1326  F1Buffer.Fill(uint64_t(0)); F2Buffer.Fill(uint64_t(0));
1327 
1328  // I need to be in ascending line order...
1330 
1331  // Generate transmit data for each of my packets...
1332  for (AJAAncDataListConstIter it(m_ancList.begin()); it != m_ancList.end(); ++it)
1333  {
1334  uint32_t pktSize(0);
1335  AJAAncillaryData * pPkt(*it);
1336  if (!pPkt)
1337  {status = AJA_STATUS_NULL; break;} // Fail
1338 
1339  if (inIsProgressive || pPkt->GetLocationLineNumber() < inF2StartLine)
1340  {
1341  if (pF1AncData && maxF1Data)
1342  {
1343  status = pPkt->GenerateTransmitData(pF1AncData, maxF1Data, pktSize);
1344  if (AJA_FAILURE(status))
1345  break;
1346 
1347  pF1AncData += pktSize;
1348  maxF1Data -= pktSize;
1349  }
1350  }
1351  else if (pF2AncData && maxF2Data)
1352  {
1353  status = pPkt->GenerateTransmitData(pF2AncData, maxF2Data, pktSize);
1354  if (AJA_FAILURE(status))
1355  break;
1356 
1357  pF2AncData += pktSize;
1358  maxF2Data -= pktSize;
1359  }
1360  } // for each of my anc packets
1361  return status;
1362 }
1363 
1364 
1366 {
1367  if (inFrameBuffer.IsNULL())
1368  {
1369  LOGMYERROR("AJA_STATUS_NULL: null frame buffer");
1370  return AJA_STATUS_NULL;
1371  }
1372  if (!inFormatDesc.IsValid())
1373  {
1374  LOGMYERROR("AJA_STATUS_BAD_PARAM: Invalid format descriptor");
1375  return AJA_STATUS_BAD_PARAM;
1376  }
1377  if (!inFormatDesc.IsVANC())
1378  {
1379  LOGMYERROR("AJA_STATUS_BAD_PARAM: Not a VANC geometry");
1380  return AJA_STATUS_BAD_PARAM;
1381  }
1382  if (inFormatDesc.GetPixelFormat() != NTV2_FBF_10BIT_YCBCR && inFormatDesc.GetPixelFormat() != NTV2_FBF_8BIT_YCBCR)
1383  {
1384  LOGMYERROR("AJA_STATUS_UNSUPPORTED: unsupported pixel format: " << inFormatDesc);
1385  return AJA_STATUS_UNSUPPORTED;
1386  }
1387  if (!CountAncillaryData())
1388  {
1389  LOGMYWARN("List is empty");
1390  return AJA_STATUS_SUCCESS;
1391  }
1392 
1393  // I need to be in ascending line order...
1395 
1396  // BRUTE-FORCE METHOD -- NOT VERY EFFICIENT
1397  const bool isSD (inFormatDesc.IsSD());
1398  AJAAncillaryList failures, successes;
1399  set <uint16_t> lineOffsetsWritten;
1400 
1401  // For each VANC line...
1402  for (UWord fbLineOffset(0); fbLineOffset < inFormatDesc.GetFirstActiveLine(); fbLineOffset++)
1403  {
1404  ULWord smpteLine (0); bool isF2 (false);
1405  inFormatDesc.GetSMPTELineNumber (fbLineOffset, smpteLine, isF2);
1406 
1407  // Look for non-HANC packets destined for this line...
1408  for (AJAAncDataListConstIter iter(m_ancList.begin()); (iter != m_ancList.end()) && *iter; ++iter)
1409  {
1410  bool muxedOK (false);
1411  AJAAncillaryData & ancData (**iter);
1412  const AJAAncDataLoc & loc (ancData.GetDataLocation());
1413  UWordSequence u16PktComponents;
1414  if (ancData.GetDataCoding() != AJAAncDataCoding_Digital) // Ignore "Raw" or "Analog" or "Unknown" packets
1415  continue;
1416  if (loc.GetDataSpace() != AJAAncDataSpace_VANC) // Ignore "HANC" or "Unknown" packets
1417  {
1418  //LOGMYWARN("Skipping non-VANC packet " << ancData);
1419  continue;
1420  }
1421  if (loc.GetLineNumber() != smpteLine) // Wrong line number
1422  {
1423  //LOGMYWARN("Skipping packet not destined for line " << DEC(smpteLine) << " " << loc);
1424  continue;
1425  }
1426  if (!IS_VALID_AJAAncDataChannel(loc.GetDataChannel())) // Bad data channel
1427  {
1428  LOGMYWARN("Skipped packet with invalid data channel " << loc);
1429  continue;
1430  }
1431 
1432  // For v210 buffers, generate 10-bit packet data and put into u16 vector...
1433  muxedOK = AJA_SUCCESS(ancData.GenerateTransmitData(u16PktComponents));
1434  if (muxedOK)
1435  {
1436  if (inFormatDesc.GetPixelFormat() == NTV2_FBF_8BIT_YCBCR) // 2vuy buffers are simple -- just copy the data
1437  {
1438  uint8_t * pLine (reinterpret_cast<uint8_t*>(inFormatDesc.GetWriteableRowAddress(inFrameBuffer.GetHostPointer(), fbLineOffset)));
1439  if (isSD)
1440  { // SD overwrites both Y & C channels in the frame buffer:
1441  for (unsigned ndx(0); ndx < u16PktComponents.size(); ndx++)
1442  pLine[ndx] = uint8_t(u16PktComponents[ndx] & 0xFF);
1443  }
1444  else
1445  { // HD overwrites only the Y or C channel data in the frame buffer:
1446  unsigned dstNdx(loc.IsLumaChannel() ? 1 : 0);
1447  for (unsigned srcNdx(0); srcNdx < u16PktComponents.size(); srcNdx++)
1448  pLine[dstNdx + 2*srcNdx] = uint8_t(u16PktComponents[srcNdx] & 0x00FF);
1449  }
1450  } // if 2vuy
1451  else
1452  {
1453  if (isSD)
1454  { // For SD, just pack the u16 components into the buffer...
1455  while (u16PktComponents.size() < 12 || u16PktComponents.size() % 12) // YUVComponentsTo10BitYUVPackedBuffer fails if packing fewer than 12 words
1456  u16PktComponents.push_back(0x040); // SMPTE black
1457  muxedOK = ::YUVComponentsTo10BitYUVPackedBuffer (u16PktComponents, inFrameBuffer, inFormatDesc, fbLineOffset);
1458  }
1459  else
1460  { // HD overwrites only the Y or C channel data:
1461  UWordSequence YUV16Line;
1462  unsigned dstNdx (loc.IsLumaChannel() ? 1 : 0);
1463 
1464  // Read original Y+C components from FB...
1465  muxedOK = UnpackLine_10BitYUVtoU16s (YUV16Line, inFrameBuffer, inFormatDesc, fbLineOffset);
1466  //cerr << "WriteVANCData|orig: +" << DEC0N(fbLineOffset,2) << ": "; inFormatDesc.PrintSMPTELineNumber(cerr, fbLineOffset); cerr << ":" << endl << YUV16Line << endl;
1467 
1468  // Patch the Y or C channel...
1469  if (muxedOK)
1470  for (unsigned srcNdx(0); srcNdx < u16PktComponents.size(); srcNdx++)
1471  YUV16Line[dstNdx + 2*srcNdx] = u16PktComponents[srcNdx] & 0x03FF;
1472  //cerr << "WriteVANCData|modi: +" << DEC0N(fbLineOffset,2) << ": "; inFormatDesc.PrintSMPTELineNumber(cerr, fbLineOffset); cerr << ":" << endl << YUV16Line << endl;
1473 
1474  // Repack the patched YUV16 line back into the FB...
1475  if (muxedOK)
1476  {
1477  while (YUV16Line.size() < 12 || YUV16Line.size() % 12) // YUVComponentsTo10BitYUVPackedBuffer fails if packing fewer than 12 words
1478  YUV16Line.push_back(0x040); // SMPTE black
1479  muxedOK = ::YUVComponentsTo10BitYUVPackedBuffer (YUV16Line, inFrameBuffer, inFormatDesc, fbLineOffset);
1480  }
1481  } // else HD
1482  } // else v210
1483  } // if GenerateTransmitData OK
1484 
1485  // TBD: NEED TO TAKE INTO CONSIDERATION loc.GetHorizontalOffset()
1486 
1487  if (muxedOK)
1488  {
1489  lineOffsetsWritten.insert(uint16_t(fbLineOffset)); // Remember which FB line offsets we overwrote
1490  successes.AddAncillaryData(ancData);
1491  }
1492  else
1493  failures.AddAncillaryData(ancData);
1494  } // for each packet
1495  } // for each VANC line
1496 
1497  // Any analog packets?
1498  for (AJAAncDataListConstIter iter(m_ancList.begin()); (iter != m_ancList.end()) && *iter; ++iter)
1499  {
1500  bool success (inFormatDesc.IsSD());
1501  AJAAncillaryData & ancData (**iter);
1502  const AJAAncDataLoc & loc (ancData.GetDataLocation());
1503  ULWord lineOffset (0);
1504  if (!ancData.IsRaw())
1505  continue; // Ignore "Digital" or "Unknown" packets
1506 
1507  if (success)
1508  success = inFormatDesc.GetLineOffsetFromSMPTELine (loc.GetLineNumber(), lineOffset);
1509  if (success && lineOffsetsWritten.find(uint16_t(lineOffset)) != lineOffsetsWritten.end())
1510  success = false; // Line already written -- "analog" data overwrites entire line
1511  if (success)
1512  {
1513  if (inFormatDesc.GetPixelFormat() == NTV2_FBF_8BIT_YCBCR)
1514  ::memcpy(inFormatDesc.GetWriteableRowAddress(inFrameBuffer.GetHostPointer(), lineOffset), ancData.GetPayloadData(), ancData.GetDC()); // '2vuy' -- straight copy
1515  else
1516  {
1517  UWordSequence pktComponentData;
1518  success = AJA_SUCCESS(ancData.GenerateTransmitData(pktComponentData));
1519  if (success)
1520  success = ::YUVComponentsTo10BitYUVPackedBuffer (pktComponentData, inFrameBuffer, inFormatDesc, UWord(lineOffset));
1521  }
1522  }
1523 
1524  if (success)
1525  {
1526  lineOffsetsWritten.insert(uint16_t(lineOffset)); // Remember which FB line offsets we overwrote
1527  successes.AddAncillaryData(ancData);
1528  }
1529  else
1530  failures.AddAncillaryData(ancData);
1531  } // for each Analog packet
1532 
1533  if (failures.CountAncillaryData())
1534  LOGMYWARN("FAILURES: " << failures);
1535  if (successes.CountAncillaryData())
1536  LOGMYDEBUG("SUCCESSES: " << successes);
1537 
1538  // At least one success is considered SUCCESS.
1539  // Zero successes and one or more failures is considered FAIL...
1540  return successes.CountAncillaryData() == 0 && failures.CountAncillaryData() > 0 ? AJA_STATUS_FAIL : AJA_STATUS_SUCCESS;
1541 } // WriteVANCData
1542 
1543 
1544 // STATIC
1545 AJAStatus AJAAncillaryList::WriteRTPPackets (NTV2Buffer & theBuffer, uint32_t & outBytesWritten,
1546  const AJAU32Pkts & inRTPPkts, const AJAAncPktCounts & inAncCounts,
1547  const bool inIsF2, const bool inIsProgressive)
1548 {
1549  const ULWord totPkts (ULWord(inRTPPkts.size()));
1550  const string sFld (inIsF2 ? " F2" : " F1");
1551  const string sPrg (inIsProgressive ? " Prg" : " Int");
1552  ULWord u32offset(0), pktNum(1);
1553 
1554  outBytesWritten = 0;
1555  if (inRTPPkts.size() != inAncCounts.size())
1556  {LOGMYERROR(DEC(inRTPPkts.size()) << " RTP pkt(s) != " << DEC(inAncCounts.size()) << " anc count(s)"); return AJA_STATUS_BAD_PARAM;}
1557 
1558  // For each RTP Packet...
1559  for (AJAU32PktsConstIter RTPPktIter(inRTPPkts.begin()); RTPPktIter != inRTPPkts.end(); pktNum++)
1560  {
1561  AJARTPAncPayloadHeader RTPHeader; // The RTP packet header to be built
1562  ULWordSequence RTPHeaderU32s; // The RTP packet header expressed as a sequence of 5 x U32s
1563  const ULWordSequence & origRTPPkt(*RTPPktIter); // The original RTP packet data contents, a sequence of U32s
1564  const bool isLastRTPPkt (++RTPPktIter == inRTPPkts.end()); // Last RTP packet?
1565  const size_t totalRTPPktBytes(AJARTPAncPayloadHeader::GetHeaderByteCount() // RTP packet size,
1566  + origRTPPkt.size() * sizeof(uint32_t)); // including header, in bytes
1567  ostringstream pktNumInfo;
1568  pktNumInfo << " for RTP pkt " << DEC(pktNum) << " of " << DEC(totPkts);
1569 
1570  // Set the RTP Packet Header's info...
1571  if (inIsProgressive)
1572  RTPHeader.SetProgressive();
1573  else if (inIsF2)
1574  RTPHeader.SetField2();
1575  else
1576  RTPHeader.SetField1();
1577  RTPHeader.SetEndOfFieldOrFrame(isLastRTPPkt);
1578  RTPHeader.SetAncPacketCount(uint8_t(inAncCounts.at(pktNum-1))); // Use provided Anc count
1579  RTPHeader.SetPayloadLength(uint16_t(origRTPPkt.size() * sizeof(uint32_t)));
1580  // Playout: Firmware looks for full RTP pkt bytecount in LS 16 bits of SequenceNumber in RTP header:
1581  RTPHeader.SetSequenceNumber(uint32_t(totalRTPPktBytes) & 0x0000FFFF);
1582 
1583  // Convert RTP header object into 5 x U32s...
1584  RTPHeader.WriteToULWordVector(RTPHeaderU32s, true);
1585  NTV2_ASSERT(RTPHeaderU32s.size() == AJARTPAncPayloadHeader::GetHeaderWordCount());
1586 
1587  // Write RTP header into theBuffer...
1588  if (theBuffer)
1589  {
1590  if (!theBuffer.PutU32s(RTPHeaderU32s, u32offset))
1591  {LOGMYERROR("RTP hdr WriteBuffer failed for buffer " << theBuffer << " at u32offset=" << DEC(u32offset)
1592  << pktNumInfo.str()); return AJA_STATUS_FAIL;}
1593  }
1594  u32offset += ULWord(RTPHeaderU32s.size()); // Move "write head" to just past end of RTP header
1595 
1596  // Write RTP packet contents into theBuffer...
1597  if (theBuffer)
1598  {
1599  if (!theBuffer.PutU32s(origRTPPkt, u32offset))
1600  {LOGMYERROR("PutU32s failed writing " << DEC(origRTPPkt.size()) << " U32s in buffer " << theBuffer << " at u32offset=" << DEC(u32offset)
1601  << pktNumInfo.str()); return AJA_STATUS_FAIL;}
1602  LOGMYDEBUG("PutU32s OK @u32offset=" << xHEX0N(u32offset,4) << ": " << RTPHeader << pktNumInfo.str());
1603  }
1604 
1605  // Move "write head" to just past where this RTP packet's data ended...
1606  u32offset += ULWord(origRTPPkt.size());
1607 
1608  // JeffL: IP Anc inserters expect subsequent RTP packets to start on a 64-bit/8-byte word boundary.
1609  if (u32offset & 1L) // If it's not even...
1610  u32offset++; // ...then make it even!
1611  } // for each RTP packet
1612 
1613  outBytesWritten = u32offset * ULWord(sizeof(uint32_t));
1614  if (theBuffer)
1615  LOGMYDEBUG(DEC(totPkts) << " RTP pkt(s), " << DEC(u32offset) << " U32s (" << DEC(outBytesWritten)
1616  << " bytes) written for" << sFld << sPrg);
1617  return AJA_STATUS_SUCCESS;
1618 }
1619 
1620 
1622  const bool inIsProgressive, const uint32_t inF2StartLine)
1623 {
1624  AJAStatus result (AJA_STATUS_SUCCESS);
1625  AJAU32Pkts F1U32Pkts, F2U32Pkts; // 32-bit network-byte-order data
1626  AJAAncPktCounts F1AncCounts, F2AncCounts; // Per-RTP packet anc packet counts
1627  uint32_t byteCount(0); // Not used
1628 
1629  // I need to be in ascending line order...
1630  F1Buffer.Fill(uint64_t(0)); F2Buffer.Fill(uint64_t(0));
1632 
1633  // Get F1 & F2 xmit RTP U32 words (and SMPTE anc packet counts for each RTP packet)...
1634  result = GetRTPPackets (F1U32Pkts, F2U32Pkts, F1AncCounts, F2AncCounts, inIsProgressive, inF2StartLine);
1635  if (AJA_FAILURE(result))
1636  return result;
1637 
1638  /*
1639  ostringstream oss; oss << "Anc Counts: F1="; for (size_t ndx(0); ndx < F1AncCounts.size(); ndx++) oss << (ndx?"|":"[") << DEC(uint16_t(F1AncCounts.at(ndx)));
1640  oss << "] F2="; for (size_t ndx(0); ndx < F2AncCounts.size(); ndx++) oss << (ndx?"|":"[") << DEC(uint16_t(F2AncCounts.at(ndx))); oss << "]";
1641  XMTDBG(oss.str());
1642  */
1643 
1644  // Write the F1 buffer...
1645  result = WriteRTPPackets (F1Buffer, byteCount, F1U32Pkts, F1AncCounts, /*isF2*/false, inIsProgressive);
1646  if (AJA_FAILURE(result))
1647  return result;
1648 
1649  // Write the F2 buffer...
1650  if (!inIsProgressive)
1651  result = WriteRTPPackets (F2Buffer, byteCount, F2U32Pkts, F2AncCounts, /*isF2*/true, inIsProgressive);
1652 
1653  return result;
1654 
1655 } // GetIPTransmitData
1656 
1657 
1658 AJAStatus AJAAncillaryList::GetIPTransmitDataLength (uint32_t & outF1ByteCount, uint32_t & outF2ByteCount,
1659  const bool inIsProgressive, const uint32_t inF2StartLine)
1660 {
1661  outF1ByteCount = outF2ByteCount = 0;
1662 
1663  // Get F1 & F2 xmit RTP U32 words...
1664  AJAU32Pkts F1U32Pkts, F2U32Pkts; // U32 network-byte-order data
1665  AJAAncPktCounts F1AncCounts, F2AncCounts; // Per-RTP packet anc packet counts
1666  AJAStatus result (GetRTPPackets (F1U32Pkts, F2U32Pkts, F1AncCounts, F2AncCounts, inIsProgressive, inF2StartLine));
1667  if (AJA_FAILURE(result))
1668  return result;
1669 
1670  NTV2Buffer nullBuffer; // An empty buffer tells WriteRTPPackets to just calculate byteCount...
1671  result = WriteRTPPackets (nullBuffer, outF1ByteCount, F1U32Pkts, F1AncCounts, /*isF2*/false, inIsProgressive);
1672  if (AJA_SUCCESS(result) && !inIsProgressive)
1673  result = WriteRTPPackets (nullBuffer, outF2ByteCount, F2U32Pkts, F2AncCounts, /*isF2*/true, inIsProgressive);
1674 
1675  return result;
1676 }
1677 
1678 
1679 ostream & AJAAncillaryList::Print (ostream & inOutStream, const bool inDumpPayload) const
1680 {
1681  unsigned num (0);
1682  inOutStream << DEC(CountAncillaryData()) << " pkts:" << endl;
1683  for (AJAAncDataListConstIter it(m_ancList.begin()); it != m_ancList.end(); )
1684  {
1685  AJAAncillaryData * pPkt(*it);
1686  inOutStream << "Pkt" << DEC0N(++num,3) << ": " << pPkt->AsString(inDumpPayload ? 16 : 0);
1687  if (++it != m_ancList.end())
1688  inOutStream << endl;
1689  }
1690  return inOutStream;
1691 }
1692 
1693 // Copies GUMP from inSrc to outDst buffers, but removes ATC, VPID, EDH, VITC & analog packets
1695 {
1696  if (!inSrc || !outDst)
1697  return false; // Buffers must be valid
1698  if (inSrc.GetByteCount() > outDst.GetByteCount())
1699  return false; // Target buffer must be at least as large as source buffer
1700 
1701  uint8_t * srcPtr = inSrc;
1702  uint8_t * ptr = srcPtr;
1703  size_t srcBufSize = inSrc;
1704  uint8_t * tgtPtr = outDst;
1705  size_t uncopied = 0;
1706 // size_t numStripped = 0;
1707 // size_t bytesRemoved = 0;
1708  const size_t kGUMPHeaderSize(7);
1709 
1710  for (size_t ndx(0); ndx < srcBufSize; )
1711  {
1712  if (ptr[0] == 0xff && (ndx + kGUMPHeaderSize) < srcBufSize)
1713  {
1714  bool bFiltered{false};
1715  const uint8_t payloadSize(ptr[5]);
1716 
1717  if (ptr[1] & 0x40) // "Analog/raw"
1718  bFiltered = true;
1719  else if (ptr[3] == 0x60 && ptr[4] == 0x60 && payloadSize == 16) // ATC
1720  bFiltered = true;
1721  else if (ptr[3] == 0x41 && ptr[4] == 0x01 && payloadSize == 4) // SMPTE 352 - VPID
1722  bFiltered = true;
1723  else if (ptr[3] == 0xF4 && ptr[4] == 0x00 && payloadSize == 16) // RP165 EDH
1724  bFiltered = true;
1725  else // VITC
1726  {
1727  const uint16_t lineNum (uint16_t((ptr[1] & 0x0F) << 7) + uint16_t(ptr[2] & 0x7F));
1728  bFiltered = (ptr[1] & 0x40) && (lineNum == 14 || lineNum == 277);
1729  }
1730 
1731  if (bFiltered)
1732  { // Copy everything that came before filtered content...
1733  if (uncopied)
1734  ::memcpy(tgtPtr, srcPtr, uncopied);
1735 
1736  // Skip srcPtr past the filtered content...
1737  srcPtr += uncopied + payloadSize + kGUMPHeaderSize;
1738  tgtPtr += uncopied;
1739  ndx += payloadSize + kGUMPHeaderSize;
1740  ptr = srcPtr;
1741  uncopied = 0;
1742 // numStripped++; bytesRemoved += size_t(payloadSize) + kGUMPHeaderSize;
1743  }
1744  else
1745  {
1746  ptr += payloadSize + kGUMPHeaderSize;
1747  ndx += payloadSize + kGUMPHeaderSize;
1748  uncopied += payloadSize + kGUMPHeaderSize;
1749  }
1750  }
1751  else
1752  {ptr++; ndx++; uncopied++;}
1753  } // for each byte in source buffer
1754 
1755  if (uncopied) // Any uncopied remainder?
1756  ::memcpy(tgtPtr, srcPtr, uncopied); // Copy last uncopied bytes
1757  // cout << DEC(numStripped) << " pkts removed, " << DEC(bytesRemoved) << " bytes removed" << endl;
1758  return true;
1759 } // StripNativeInserterPackets
1760 
1761 
1765 
1768 
1769 
1771 {
1773  gAnalogTypeMap.clear();
1774  return AJA_STATUS_SUCCESS;
1775 }
1776 
1777 
1779 {
1781  gAnalogTypeMap = inMap;
1782  return AJA_STATUS_SUCCESS;
1783 }
1784 
1785 
1787 {
1789  outMap = gAnalogTypeMap;
1790  return AJA_STATUS_SUCCESS;
1791 }
1792 
1793 
1795 {
1797  gAnalogTypeMap.erase(inLineNum); // In case someone has already set this line
1798  if (inAncType == AJAAncDataType_Unknown)
1799  return AJA_STATUS_SUCCESS; // A non-entry is the same as AJAAncDataType_Unknown
1800  else if (IS_VALID_AJAAncDataType(inAncType))
1801  gAnalogTypeMap[inLineNum] = inAncType;
1802  else
1803  return AJA_STATUS_BAD_PARAM;
1804  return AJA_STATUS_SUCCESS;
1805 }
1806 
1807 
1809 {
1812  if (!gAnalogTypeMap.empty ())
1813  {
1814  AJAAncillaryAnalogTypeMap::const_iterator it (gAnalogTypeMap.find (inLineNum));
1815  if (it != gAnalogTypeMap.end ())
1816  ancType = it->second;
1817  }
1818  return ancType;
1819 }
gGlobalLock
static AJALock gGlobalLock
Definition: ancillarylist.cpp:123
AJAAncillaryList::AllowMultiRTPReceive
virtual bool AllowMultiRTPReceive(void) const
Answers true if multiple RTP packets are allowed for capture/receive. The default behavior is to proc...
Definition: ancillarylist.h:564
AJAAncPktCounts
UByteSequence AJAAncPktCounts
Ordered sequence of SMPTE Anc packet counts.
Definition: ancillarylist.h:42
AJAAncBufferFormat_FBVANC
@ AJAAncBufferFormat_FBVANC
Frame buffer VANC lines.
Definition: ancillarydata.h:499
AJA_STATUS_BADBUFFERSIZE
@ AJA_STATUS_BADBUFFERSIZE
Definition: types.h:411
ULWordSequenceToStringBE
static string ULWordSequenceToStringBE(const ULWordSequence &inData, const size_t inMaxNum=32)
Definition: ancillarylist.cpp:87
SortByDID
static bool SortByDID(AJAAncillaryData *lhs, AJAAncillaryData *rhs)
Definition: ancillarylist.cpp:456
AJAAncillaryList::AJAAncillaryDataList
std::vector< AJAAncillaryData * > AJAAncillaryDataList
Definition: ancillarylist.h:629
ULWordSequenceConstIter
ULWordSequence::const_iterator ULWordSequenceConstIter
A handy const iterator for iterating over a ULWordSequence.
Definition: ntv2publicinterface.h:47
AJAAncillaryList::ClearAnalogAncillaryDataTypeMap
static AJAStatus ClearAnalogAncillaryDataTypeMap(void)
Clears my global Analog Ancillary Data Type map.
Definition: ancillarylist.cpp:1770
AJAAncillaryData::GetRawPacketSize
virtual AJAStatus GetRawPacketSize(uint32_t &outPacketSize) const
Returns the number of "raw" ancillary data bytes that will be generated by AJAAncillaryData::Generate...
Definition: ancillarydata.cpp:726
AJAAncDataLoc
Defines where the ancillary data can be found within a video stream.
Definition: ancillarydata.h:225
AppendUWordPacketToGump
static AJAStatus AppendUWordPacketToGump(UByteSequence &outGumpPkt, const UWordSequence &inPacketWords, const AJAAncDataLoc inLoc=AJAAncDataLoc(AJAAncDataLink_A, AJAAncDataChannel_Y, AJAAncDataSpace_VANC, 0))
Definition: ancillarylist.cpp:833
AJARTPAncPayloadHeader::SetAncPacketCount
virtual AJARTPAncPayloadHeader & SetAncPacketCount(const uint8_t inPktCount)
Sets my RTP Anc Packet Count value.
Definition: ancillarydata.h:1337
AJAAncillaryList::AddVANCData
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.
Definition: ancillarylist.cpp:882
NTV2Buffer::GetU32s
bool GetU32s(ULWordSequence &outU32s, const size_t inU32Offset=0, const size_t inMaxSize=32, const bool inByteSwap=false) const
Answers with my contents as a vector of unsigned 32-bit values.
Definition: ntv2publicinterface.cpp:604
AJAAncillaryList::Compare
virtual AJAStatus Compare(const AJAAncillaryList &inCompareList, const bool inIgnoreLocation=true, const bool inIgnoreChecksum=true) const
Compares me with another list.
Definition: ancillarylist.cpp:509
AJAAncillaryList::GetAncillaryDataTransmitData
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...
Definition: ancillarylist.cpp:1308
AJAAncDataType_Unknown
@ AJAAncDataType_Unknown
Includes data that is valid, but we don't recognize.
Definition: ancillarydata.h:46
NTV2FormatDescriptor
Describes a video frame for a given video standard or format and pixel format, including the total nu...
Definition: ntv2formatdescriptor.h:41
NTV2FormatDescriptor::GetRowAddress
const void * GetRowAddress(const void *pInStartAddress, const ULWord inRowIndex0, const UWord inPlaneIndex0=0) const
Definition: ntv2formatdescriptor.cpp:1092
AJAAncillaryList::SetAnalogAncillaryDataTypeMap
static AJAStatus SetAnalogAncillaryDataTypeMap(const AJAAncillaryAnalogTypeMap &inMap)
Copies the given map to the global Analog Ancillary Data Type map.
Definition: ancillarylist.cpp:1778
AJAAncillaryList::RemoveAncillaryData
virtual AJAStatus RemoveAncillaryData(AJAAncillaryData *pInAncData)
Removes all copies of the AJAAncillaryData object from me.
Definition: ancillarylist.cpp:420
AJAAncillaryList::SetFromDeviceAncBuffers
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.
Definition: ancillarylist.cpp:1118
NTV2Buffer
Describes a user-space buffer on the host computer. I have an address and a length,...
Definition: ntv2publicinterface.h:6094
AJA_STATUS_SUCCESS
@ AJA_STATUS_SUCCESS
Definition: types.h:381
ToAJAAncPktDIDSID
#define ToAJAAncPktDIDSID(_d_, _s_)
Definition: ancillarydata.h:29
AJA_STATUS_NOT_FOUND
@ AJA_STATUS_NOT_FOUND
Definition: types.h:402
NTV2Buffer::GetByteCount
ULWord GetByteCount(void) const
Definition: ntv2publicinterface.h:6168
XMTDBG
#define XMTDBG(__x__)
Definition: ancillarylist.cpp:46
NTV2_ASSERT
#define NTV2_ASSERT(_expr_)
Definition: ajatypes.h:508
AJAAncillaryList::SetFromDeviceAuxBuffers
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.
Definition: ancillarylist.cpp:1135
NTV2Buffer::IsProvidedByClient
bool IsProvidedByClient(void) const
Definition: ntv2publicinterface.h:6180
AJAAncillaryList::GetIPTransmitData
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 ....
Definition: ancillarylist.cpp:1621
UByteSequence
std::vector< uint8_t > UByteSequence
An ordered sequence of UByte (uint8_t) values.
Definition: ntv2publicinterface.h:38
AJAAncPktDIDSIDSet
std::set< AJAAncPktDIDSID > AJAAncPktDIDSIDSet
Set of distinct packet DID/SIDs (New in SDK 16.0)
Definition: ancillarylist.h:44
AncChannelSearch_C
@ AncChannelSearch_C
Only look in chroma samples.
Definition: ancillarydata.h:155
ancillarylist.h
Declares the AJAAncillaryList class.
YUVComponentsTo10BitYUVPackedBuffer
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.
AJAAncillaryData::GetAncPacketsFromVANCLine
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.
Definition: ancillarydata.cpp:1710
AJAU32PktsConstIter
AJAU32Pkts::const_iterator AJAU32PktsConstIter
Handy const iterator over AJAU32Pkts.
Definition: ancillarylist.h:39
NTV2FormatDescriptor::GetVisibleRasterBytes
ULWord GetVisibleRasterBytes(const UWord inPlaneIndex0=0) const
Definition: ntv2formatdescriptor.h:152
AJAAncDataType
AJAAncDataType
Identifies the ancillary data types that are known to this module.
Definition: ancillarydata.h:44
AJAAncillaryList::CountAncillaryDataWithType
virtual uint32_t CountAncillaryDataWithType(const AJAAncDataType inMatchType) const
Answers with the number of AJAAncillaryData objects having the given type.
Definition: ancillarylist.cpp:264
UnpackLine_10BitYUVtoUWordSequence
bool UnpackLine_10BitYUVtoUWordSequence(const void *pIn10BitYUVLine, const NTV2FormatDescriptor &inFormatDesc, UWordSequence &out16BitYUVLine)
Unpacks a line of NTV2_FBF_10BIT_YCBCR video into 16-bit-per-component YUV data.
Definition: ntv2utils.cpp:143
AJAAncillaryData::InitAuxWithReceivedData
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 Fo...
Definition: ancillarydata.cpp:624
AJAAncillaryData::InitWithReceivedData
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 Fo...
Definition: ancillarydata.cpp:512
AJAAncillaryList::ParseAllAncillaryData
virtual AJAStatus ParseAllAncillaryData(void)
Sends a "ParsePayloadData" command to all of my AJAAncillaryData objects.
Definition: ancillarylist.cpp:247
DEC0N
#define DEC0N(__x__, __n__)
Definition: ntv2publicinterface.h:5649
AJAAncillaryList::GetAncillaryDataWithID
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.
Definition: ancillarylist.cpp:323
RCVDBG
#define RCVDBG(__x__)
Definition: ancillarylist.cpp:40
NTV2FrameBufferFormat
NTV2FrameBufferFormat
Identifies a particular video frame buffer format. See Device Frame Buffer Formats for details.
Definition: ntv2enums.h:210
ancillarydatafactory.h
Declaration of the AJAAncillaryDataFactory class.
NTV2Buffer::PutU32s
bool PutU32s(const ULWordSequence &inU32s, const size_t inU32Offset=0, const bool inByteSwap=false)
Copies a vector of unsigned 32-bit values into me.
Definition: ntv2publicinterface.cpp:798
NTV2FormatDescriptor::GetLineOffsetFromSMPTELine
bool GetLineOffsetFromSMPTELine(const ULWord inSMPTELine, ULWord &outLineOffset) const
Answers with the equivalent line offset into the raster I describe for the given SMPTE line number.
Definition: ntv2formatdescriptor.cpp:1295
AJAAncillaryList::GetAncillaryPacketIDs
virtual AJAAncPktDIDSIDSet GetAncillaryPacketIDs(void) const
Definition: ancillarylist.cpp:346
AJAAncillaryList::GetAncillaryDataWithType
virtual AJAAncillaryData * GetAncillaryDataWithType(const AJAAncDataType inMatchType, const uint32_t inIndex=0) const
Answers with the AJAAncillaryData object having the given type and index.
Definition: ancillarylist.cpp:280
ENDIAN_32NtoH
static uint32_t ENDIAN_32NtoH(const uint32_t inValue)
Definition: ancillarylist.cpp:66
AJA_ENDIAN_32NtoH
#define AJA_ENDIAN_32NtoH(__val__)
Definition: ancillarylist.cpp:60
AJAAncillaryList
I am an ordered collection of AJAAncillaryData instances which represent one or more SMPTE 291 data p...
Definition: ancillarylist.h:64
AJAAncillaryList::SortListBySID
virtual AJAStatus SortListBySID(void)
Sort the AncillaryDataList by Secondary ID (SID) value.
Definition: ancillarylist.cpp:488
AJAAncBufferFormat_HDMI
@ AJAAncBufferFormat_HDMI
HDMI.
Definition: ancillarydata.h:502
LOGMYDEBUG
#define LOGMYDEBUG(__x__)
Definition: ancillarylist.cpp:34
AJARTPAncPayloadHeader::SetEndOfFieldOrFrame
virtual AJARTPAncPayloadHeader & SetEndOfFieldOrFrame(const bool inIsLast=true)
Sets my RTP Packet End-Of-Field or End-Of-Frame (Marker Bit) value.
Definition: ancillarydata.h:1372
AJAAncillaryData::Unpack8BitYCbCrToU16sVANCLine
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...
Definition: ancillarydata.cpp:1782
AJAAncillaryList::SetIncludeZeroLengthPackets
static void SetIncludeZeroLengthPackets(const bool inExclude)
Sets whether or not zero-length packets are included or not.
Definition: ancillarylist.cpp:140
AJAAncillaryDataFactory::Create
static AJAAncillaryData * Create(const AJAAncDataType inAncType, const AJAAncillaryData &inAncData)
Creates a new particular subtype of AJAAncillaryData object.
Definition: ancillarydatafactory.cpp:23
AJAAncDataLoc::IsLumaChannel
bool IsLumaChannel(void) const
Definition: ancillarydata.h:307
AJAAncillaryList::GetAnalogAncillaryDataTypeMap
static AJAStatus GetAnalogAncillaryDataTypeMap(AJAAncillaryAnalogTypeMap &outMap)
Returns a copy of the global Analog Ancillary Data Type map.
Definition: ancillarylist.cpp:1786
AJAStatus
AJAStatus
Definition: types.h:378
AJAAncillaryList::AJAAncDataListConstIter
AJAAncillaryDataList::const_iterator AJAAncDataListConstIter
Handy const iterator for iterating over members of an AJAAncillaryDataList.
Definition: ancillarylist.h:633
AJAAncillaryAnalogTypeMap
std::map< uint16_t, AJAAncDataType > AJAAncillaryAnalogTypeMap
Associates certain frame line numbers with specific types of "raw" or "analog" ancillary data....
Definition: ancillarylist.h:36
AJARTPAncPayloadHeader
I represent the header of a SMPTE 2110 compliant RTP Anc network packet.
Definition: ancillarydata.h:1185
AJAAncillaryList::AJAAncDataListIter
AJAAncillaryDataList::iterator AJAAncDataListIter
Handy non-const iterator for iterating over members of an AJAAncillaryDataList.
Definition: ancillarylist.h:634
AJARTPAncPayloadHeader::WriteToULWordVector
virtual bool WriteToULWordVector(ULWordSequence &outVector, const bool inReset=true) const
Writes an RTP packet header based on my current state into the given ULWordSequence....
Definition: ancillarydata.cpp:2280
lock.h
Declares the AJALock class.
AJA_STATUS_FAIL
@ AJA_STATUS_FAIL
Definition: types.h:382
NTV2Buffer::IsNULL
bool IsNULL(void) const
Definition: ntv2publicinterface.h:6190
ULWord
uint32_t ULWord
Definition: ajatypes.h:255
AJAAncillaryData::Compare
virtual AJAStatus Compare(const AJAAncillaryData &inRHS, const bool inIgnoreLocation=true, const bool inIgnoreChecksum=true) const
Compares me with another packet.
Definition: ancillarydata.cpp:1510
gAnalogTypeMapMutex
static AJALock gAnalogTypeMapMutex
Definition: ancillarylist.cpp:1767
AJAAncillaryData
I am the principal class that stores a single SMPTE-291 SDI ancillary data packet OR the digitized co...
Definition: ancillarydata.h:552
AJAAncillaryList::SortListByDID
virtual AJAStatus SortListByDID(void)
Sort the AncillaryDataList by DataID (DID) value.
Definition: ancillarylist.cpp:477
AJAAncDataChannel_Y
@ AJAAncDataChannel_Y
The ancillary data is associated with the luminance (Y) channel of the video stream.
Definition: ancillarydata.h:133
AJARTPAncPayloadHeader::SetPayloadLength
virtual AJARTPAncPayloadHeader & SetPayloadLength(const uint16_t inByteCount)
Sets my RTP Packet Length value.
Definition: ancillarydata.h:1330
AJAAncillaryList::GetExcludedZeroLengthPacketCount
static uint32_t GetExcludedZeroLengthPacketCount(void)
Definition: ancillarylist.cpp:125
AJAAncillaryData::GetPayloadData
virtual const uint8_t * GetPayloadData(void) const
Definition: ancillarydata.h:801
UWordSequenceConstIter
UWordSequence::const_iterator UWordSequenceConstIter
A handy const iterator for iterating over a UWordSequence.
Definition: ntv2publicinterface.h:43
UWordSequence
std::vector< uint16_t > UWordSequence
An ordered sequence of UWord (uint16_t) values.
Definition: ntv2publicinterface.h:42
MAX_RTP_PKT_LENGTH_BYTES
static const size_t MAX_RTP_PKT_LENGTH_BYTES(0x0000FFFF)
AJARTPAncPayloadHeader::ReadFromBuffer
virtual bool ReadFromBuffer(const NTV2Buffer &inBuffer)
Resets my current state from the RTP packet header stored in the given buffer. Each 32-bit word in th...
Definition: ancillarydata.cpp:2313
AJARTPAncPayloadHeader::SetField2
virtual AJARTPAncPayloadHeader & SetField2(void)
Sets my Field Signal value to "Field 2".
Definition: ancillarydata.h:1310
AJAAncillaryList::SetAnalogAncillaryDataTypeForLine
static AJAStatus SetAnalogAncillaryDataTypeForLine(const uint16_t inLineNum, const AJAAncDataType inType)
Sets (or changes) the map entry for the designated line to the designated type.
Definition: ancillarylist.cpp:1794
UnpackLine_10BitYUVtoU16s
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...
AJAAncillaryList::DeleteAncillaryData
virtual AJAStatus DeleteAncillaryData(AJAAncillaryData *pInAncData)
Removes all copies of the AJAAncillaryData object from me and deletes the object itself.
Definition: ancillarylist.cpp:442
LOGMYINFO
#define LOGMYINFO(__x__)
Definition: ancillarylist.cpp:33
SortBySID
static bool SortBySID(AJAAncillaryData *lhs, AJAAncillaryData *rhs)
Definition: ancillarylist.cpp:462
NTV2FormatDescriptor::GetFirstActiveLine
ULWord GetFirstActiveLine(void) const
Definition: ntv2formatdescriptor.h:198
AJAAncillaryDataWildcard_DID
const uint8_t AJAAncillaryDataWildcard_DID
Definition: ancillarylist.h:27
UWord
uint16_t UWord
Definition: ajatypes.h:253
AJAAncillaryList::IsIncludingZeroLengthPackets
static bool IsIncludingZeroLengthPackets(void)
Definition: ancillarylist.cpp:135
AJAAncillaryData::AppendPayload
virtual AJAStatus AppendPayload(const AJAAncillaryData &inAncData)
Appends payload data from another AJAAncillaryData object to my existing payload.
Definition: ancillarydata.cpp:426
NTV2_FBF_8BIT_YCBCR
@ NTV2_FBF_8BIT_YCBCR
See 8-Bit YCbCr Format.
Definition: ntv2enums.h:214
ntv2utils.h
Declares numerous NTV2 utility functions.
AJAU32Pkts
std::vector< ULWordSequence > AJAU32Pkts
Ordered sequence of U32 RTP packets (U32s in network byte order)
Definition: ancillarylist.h:38
AJA_SUCCESS
#define AJA_SUCCESS(_status_)
Definition: types.h:370
AJAAncDataType_HDMI_Aux
@ AJAAncDataType_HDMI_Aux
HDMI Auxiliary data.
Definition: ancillarydata.h:60
AJAAncillaryList::GetAncillaryDataAtIndex
virtual AJAAncillaryData * GetAncillaryDataAtIndex(const uint32_t inIndex) const
Answers with the AJAAncillaryData object at the given index.
Definition: ancillarylist.cpp:227
AJAAncillaryData::AsString
virtual std::string AsString(const uint16_t inDumpMaxBytes=0) const
Definition: ancillarydata.cpp:1440
AJAAncillaryData::SetBufferFormat
virtual AJAAncillaryData & SetBufferFormat(const AJAAncBufferFormat inFmt)
Sets my originating buffer format.
Definition: ancillarydata.h:781
BumpZeroLengthPacketCount
static void BumpZeroLengthPacketCount(void)
Definition: ancillarylist.cpp:145
AJAAncBufferFormat_SDI
@ AJAAncBufferFormat_SDI
SDI (AJA "GUMP")
Definition: ancillarydata.h:500
AJAAncillaryList::AddAncillaryData
virtual AJAStatus AddAncillaryData(const AJAAncillaryList &inPackets)
Appends a copy of the given list's packets to me.
Definition: ancillarylist.cpp:359
LOGMYERROR
#define LOGMYERROR(__x__)
Definition: ancillarylist.cpp:30
AJAAncDataLoc
struct AJAAncDataLoc AJAAncDataLoc
Defines where the ancillary data can be found within a video stream.
AJAAncillaryList::StripNativeInserterGUMPPackets
static bool StripNativeInserterGUMPPackets(const NTV2Buffer &inSrc, NTV2Buffer &outDst)
Copies GUMP from inSrc to outDst buffers, but removes ATC, VPID, VITC, EDH & raw/analog packets.
Definition: ancillarylist.cpp:1694
AJAAncillaryList::Print
virtual std::ostream & Print(std::ostream &inOutStream, const bool inDetailed=true) const
Dumps a human-readable description of every packet in my list to the given output stream.
Definition: ancillarylist.cpp:1679
AJAAncillaryList::AllowMultiRTPTransmit
virtual bool AllowMultiRTPTransmit(void) const
Answers true if multiple RTP packets will be transmitted/encoded. The default behavior is to transmit...
Definition: ancillarylist.h:491
AJAAncillaryList::CountAncillaryData
virtual uint32_t CountAncillaryData(void) const
Answers with the number of AJAAncillaryData objects I contain (any/all types).
Definition: ancillarylist.h:216
AJAAncillaryList::WriteRTPPackets
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.
Definition: ancillarylist.cpp:1545
AJARTPAncPayloadHeader::SetSequenceNumber
virtual AJARTPAncPayloadHeader & SetSequenceNumber(const uint32_t inSeqNumber)
Sets my RTP Packet Sequence Number value.
Definition: ancillarydata.h:1358
IS_VALID_AJAAncDataChannel
#define IS_VALID_AJAAncDataChannel(_x_)
Definition: ancillarydata.h:138
AJAAncillaryList::GetAnalogAncillaryDataTypeForLine
static AJAAncDataType GetAnalogAncillaryDataTypeForLine(const uint16_t inLineNum)
Answers with the ancillary data type associated with the designated line.
Definition: ancillarylist.cpp:1808
AJAAncillaryList::GetAncillaryDataTransmitSize
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 ...
Definition: ancillarylist.cpp:1282
AJA_STATUS_UNSUPPORTED
@ AJA_STATUS_UNSUPPORTED
Definition: types.h:394
AJALock
Definition: lock.h:28
AJAAncillaryData::Unpack8BitYCbCrToU16sVANCLineSD
static bool Unpack8BitYCbCrToU16sVANCLineSD(const void *pInYUV8Line, UWordSequence &outU16YUVLine, const uint32_t inNumPixels)
SD version of Unpack8BitYCbCrToU16sVANCLine.
Definition: ancillarydata.cpp:1884
AJA_STATUS_RANGE
@ AJA_STATUS_RANGE
Definition: types.h:385
AJARTPAncPayloadHeader::SetProgressive
virtual AJARTPAncPayloadHeader & SetProgressive(void)
Sets my Field Signal value to "Progressive".
Definition: ancillarydata.h:1316
AJAAncillaryList::~AJAAncillaryList
virtual ~AJAAncillaryList()
My destructor.
Definition: ancillarylist.cpp:185
NTV2FormatDescriptor::GetTotalRasterBytes
ULWord GetTotalRasterBytes(const UWord inPlaneIndex0=0) const
Definition: ntv2formatdescriptor.h:132
AJA_NULL
#define AJA_NULL
Definition: ajatypes.h:199
AJAAncillaryList::CompareWithInfo
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...
Definition: ancillarylist.cpp:524
AJAAncDataLoc::SetHorizontalOffset
AJAAncDataLoc & SetHorizontalOffset(uint16_t inHOffset)
Specifies the horizontal packet position in the raster.
Definition: ancillarydata.h:408
AJAAncDataLink
AJAAncDataLink
Identifies which link of a video stream the ancillary data is associated with.
Definition: ancillarydata.h:79
AJARTPAncPayloadHeader::IsNULL
virtual bool IsNULL(void) const
Definition: ancillarydata.cpp:2361
NTV2Buffer::GetHostAddress
void * GetHostAddress(const ULWord inByteOffset, const bool inFromEnd=false) const
Definition: ntv2publicinterface.cpp:1825
AJAAncillaryList::GetVANCTransmitData
virtual AJAStatus GetVANCTransmitData(NTV2Buffer &inFrameBuffer, const NTV2FormatDescriptor &inFormatDesc)
Writes my AJAAncillaryData objects into the given tall/taller frame buffer having the given raster/fo...
Definition: ancillarylist.cpp:1365
NTV2Buffer::GetHostPointer
void * GetHostPointer(void) const
Definition: ntv2publicinterface.h:6151
AJAAutoLock
Definition: lock.h:89
AJARTPAncPayloadHeader::ReadFromULWordVector
virtual bool ReadFromULWordVector(const ULWordSequence &inVector)
Resets my current state from the RTP packet header stored in the given ULWordSequence....
Definition: ancillarydata.cpp:2302
NTV2Buffer::AsString
std::string AsString(UWord inDumpMaxBytes=0) const
Definition: ntv2publicinterface.cpp:394
LOGMYWARN
#define LOGMYWARN(__x__)
Definition: ancillarylist.cpp:31
AJAAncillaryList::CountAncillaryDataWithID
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.
Definition: ancillarylist.cpp:305
AJAAncillaryData::SetFrameID
virtual AJAAncillaryData & SetFrameID(const uint32_t inFrameID)
Sets my originating frame identifier.
Definition: ancillarydata.h:774
NTV2_FBF_10BIT_YCBCR
@ NTV2_FBF_10BIT_YCBCR
See 10-Bit YCbCr Format.
Definition: ntv2enums.h:213
AJAAtomic::Increment
static int32_t Increment(int32_t volatile *pTarget)
Definition: atomic.cpp:82
gIncludeZeroLengthPackets
static bool gIncludeZeroLengthPackets(false)
RCVWARN
#define RCVWARN(__x__)
Definition: ancillarylist.cpp:37
operator<<
ostream & operator<<(ostream &inOutStream, const AJAU32Pkts &inPkts)
Definition: ancillarylist.cpp:94
AJA_STATUS_NULL
@ AJA_STATUS_NULL
Definition: types.h:387
DEC
#define DEC(__x__)
Definition: ntv2publicinterface.h:5647
AJAAncillaryList::BufferHasGUMPData
static bool BufferHasGUMPData(const NTV2Buffer &inBuffer)
Definition: ancillarylist.h:638
MAX_RTP_PKT_LENGTH_WORDS
static const size_t MAX_RTP_PKT_LENGTH_WORDS((MAX_RTP_PKT_LENGTH_BYTES+1)/sizeof(uint32_t) - 1)
false
#define false
Definition: ntv2devicefeatures.h:25
AJAAncillaryData::Clear
virtual void Clear(void)
Frees my allocated memory, if any, and resets my members to their default values.
Definition: ancillarydata.cpp:159
PrintULWordsBE
static ostream & PrintULWordsBE(ostream &inOutStream, const ULWordSequence &inData, const size_t inMaxNum=32)
Definition: ancillarylist.cpp:69
gAnalogTypeMap
static AJAAncillaryAnalogTypeMap gAnalogTypeMap
Definition: ancillarylist.cpp:1766
NTV2FormatDescriptor::GetWriteableRowAddress
void * GetWriteableRowAddress(void *pInStartAddress, const ULWord inRowIndex0, const UWord inPlaneIndex0=0) const
Definition: ntv2formatdescriptor.cpp:1113
AJAAncDataChannel_C
@ AJAAncDataChannel_C
The ancillary data is associated with the chrominance (C) channel of the video stream.
Definition: ancillarydata.h:131
NTV2_IS_SD_STANDARD
#define NTV2_IS_SD_STANDARD(__s__)
Definition: ntv2enums.h:189
AJAAncillaryList::AddReceivedAncillaryData
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 – i...
Definition: ancillarylist.cpp:584
HEX0N
#define HEX0N(__x__, __n__)
Definition: debug.cpp:1175
NTV2FrameBufferFormatToString
std::string NTV2FrameBufferFormatToString(const NTV2FrameBufferFormat inValue, const bool inForRetailDisplay=false)
Definition: ntv2utils.cpp:6988
AJAAncillaryData::ParsePayloadData
virtual AJAStatus ParsePayloadData(void)
Parses (interprets) the "local" ancillary data from my payload data.
Definition: ancillarydata.cpp:501
AJA_STATUS_BAD_PARAM
@ AJA_STATUS_BAD_PARAM
Definition: types.h:392
AJAAncillaryList::ResetExcludedZeroLengthPacketCount
static void ResetExcludedZeroLengthPacketCount(void)
Resets my tally of excluded zero-length packets to zero.
Definition: ancillarylist.cpp:130
AJAAncillaryList::GetTransmitData
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 ...
Definition: ancillarylist.cpp:1319
std
Definition: json.hpp:5362
AJAAncillaryDataWildcard_SID
const uint8_t AJAAncillaryDataWildcard_SID
Definition: ancillarylist.h:28
AJAStatusToString
std::string AJAStatusToString(const AJAStatus inStatus, const bool inDetailed)
Definition: debug.cpp:981
AJAAncillaryList::SortListByLocation
virtual AJAStatus SortListByLocation(void)
Sort the AncillaryDataList by "location", i.e. where in the video (field, line num,...
Definition: ancillarylist.cpp:498
ULWordSequence
std::vector< uint32_t > ULWordSequence
An ordered sequence of ULWord (uint32_t) values.
Definition: ntv2publicinterface.h:46
AJAAncillaryDataFactory::GuessAncillaryDataType
static AJAAncDataType GuessAncillaryDataType(const AJAAncillaryData &inAncData)
Given a generic AJAAncillaryData object, attempts to guess what kind of specific AJAAncillaryData obj...
Definition: ancillarydatafactory.cpp:65
atomic.h
Declares the AJAAtomic class.
AJAAncillaryData::GenerateTransmitData
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 F...
Definition: ancillarydata.cpp:767
SortByLocation
static bool SortByLocation(AJAAncillaryData *lhs, AJAAncillaryData *rhs)
Definition: ancillarylist.cpp:467
AJAAncillaryList::operator=
virtual AJAAncillaryList & operator=(const AJAAncillaryList &inRHS)
Assignment operator – replaces my contents with the right-hand-side value.
Definition: ancillarylist.cpp:191
AJAAncillaryData::Clone
virtual AJAAncillaryData * Clone(void) const
Definition: ancillarydata.cpp:165
true
#define true
Definition: ntv2devicefeatures.h:26
AJAAncDataCoding_Digital
@ AJAAncDataCoding_Digital
The ancillary data is in the form of a SMPTE-291 Ancillary Packet.
Definition: ancillarydata.h:476
gExcludedZeroLengthPackets
static uint32_t gExcludedZeroLengthPackets(0)
AJAAncillaryList::GetAnalogAncillaryDataType
virtual AJAAncDataType GetAnalogAncillaryDataType(const AJAAncillaryData &inAncData)
Definition: ancillarylist.h:636
AJARTPAncPayloadHeader::SetField1
virtual AJARTPAncPayloadHeader & SetField1(void)
Sets my Field Signal value to "Field 1".
Definition: ancillarydata.h:1304
AJAAncillaryData::CompareWithInfo
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.
Definition: ancillarydata.cpp:1537
AJARTPAncPayloadHeader::BufferStartsWithRTPHeader
static bool BufferStartsWithRTPHeader(const NTV2Buffer &inBuffer)
Definition: ancillarydata.cpp:2172
RCVFAIL
#define RCVFAIL(__x__)
Definition: ancillarylist.cpp:36
AJAAncillaryList::AJAAncillaryList
AJAAncillaryList()
Instantiate and initialize with a default set of values.
Definition: ancillarylist.cpp:154
AJAAncillaryList::AddFromDeviceAuxBuffer
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.
Definition: ancillarylist.cpp:1094
AJAAncBufferFormat_RTP
@ AJAAncBufferFormat_RTP
RTP/IP.
Definition: ancillarydata.h:501
NTV2Buffer::Fill
bool Fill(const T &inValue)
Fills me with the given scalar value.
Definition: ntv2publicinterface.h:6320
AJARTPAncPayloadHeader::IsValid
virtual bool IsValid(void) const
Definition: ancillarydata.cpp:2366
AJAAncDataSpace_VANC
@ AJAAncDataSpace_VANC
Ancillary data found between SAV and EAV (.
Definition: ancillarydata.h:177
AJAAncillaryList::Clear
virtual AJAStatus Clear(void)
Removes and frees all of my AJAAncillaryData objects.
Definition: ancillarylist.cpp:399
AJAAncillaryList::GetIPTransmitDataLength
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 ...
Definition: ancillarylist.cpp:1658
AJA_STATUS_BADBUFFERCOUNT
@ AJA_STATUS_BADBUFFERCOUNT
Definition: types.h:410
AJAAncillaryList::IgnoreChecksumErrors
virtual bool IgnoreChecksumErrors(void) const
Answers if checksum errors are to be ignored or not. The default behavior is to not ignore them.
Definition: ancillarylist.h:579
xHEX0N
#define xHEX0N(__x__, __n__)
Definition: ntv2publicinterface.h:5646
AJA_FAILURE
#define AJA_FAILURE(_status_)
Definition: types.h:371
AJAAncDataType_Cea608_Line21
@ AJAAncDataType_Cea608_Line21
CEA608 SD Closed Captioning ("Line 21" waveform)
Definition: ancillarydata.h:52
AJAAncillaryList::AddFromDeviceAncBuffer
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.
Definition: ancillarylist.cpp:1013
IS_VALID_AJAAncDataType
#define IS_VALID_AJAAncDataType(_x_)
Definition: ancillarydata.h:64
AJAAncillaryList::GetRTPPackets
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...
Definition: ancillarylist.cpp:1158
NTV2FormatDescriptor::IsValid
bool IsValid(void) const
Definition: ntv2formatdescriptor.h:112
AJAAncPktDIDSIDSetConstIter
AJAAncPktDIDSIDSet::const_iterator AJAAncPktDIDSIDSetConstIter
Handy const iterator for AJAAncPktDIDSIDSet (New in SDK 16.0)
Definition: ancillarylist.h:47
NTV2FormatDescriptor::GetSMPTELineNumber
bool GetSMPTELineNumber(const ULWord inLineOffset, ULWord &outSMPTELine, bool &outIsField2) const
Answers with the equivalent SMPTE line number for the given line offset into the frame buffer I descr...
Definition: ntv2formatdescriptor.cpp:1263
MAX_ANC_PKTS_PER_RTP_PKT
static const uint32_t MAX_ANC_PKTS_PER_RTP_PKT(0x000000FF)
AJAAncDataLink_A
@ AJAAncDataLink_A
The ancillary data is associated with Link A of the video stream.
Definition: ancillarydata.h:81
AJAAncDataChannel_Both
@ AJAAncDataChannel_Both
SD ONLY – The ancillary data is associated with both the chroma and luma channels.
Definition: ancillarydata.h:132
AJAAncillaryData::U16Packets
std::vector< U16Packet > U16Packets
An ordered sequence of zero or more U16Packet values.
Definition: ancillarydata.h:1062
debug.h
Declares the AJADebug class.
AncChannelSearch_Both
@ AncChannelSearch_Both
Look both luma and chroma samples (SD only)
Definition: ancillarydata.h:156
NTV2Buffer::Set
bool Set(const void *pInUserPointer, const size_t inByteCount)
Sets (or resets) me from a client-supplied address and size.
Definition: ntv2publicinterface.cpp:1753
AJAAncillaryList::SetFromVANCData
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.
Definition: ancillarylist.cpp:922
DECN
#define DECN(__x__, __n__)
Definition: ntv2publicinterface.h:5648
AJAAncDataLoc::GetDataSpace
AJAAncDataSpace GetDataSpace(void) const
Definition: ancillarydata.h:316
AncChannelSearch_Y
@ AncChannelSearch_Y
Only look in luma samples.
Definition: ancillarydata.h:154
AJAAncillaryList::AddReceivedAuxiliaryData
virtual AJAStatus AddReceivedAuxiliaryData(const NTV2Buffer &inReceivedData, const uint32_t inFrameNum=0)
Parse "raw" HDMI auxillary data bytes received from hardware (ingest) into separate AJAAncillaryData ...
Definition: ancillarylist.cpp:709