AJA NTV2 SDK  17.1.1.1245
NTV2 SDK 17.1.1.1245
ntv2ccplayer.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
8 #include "ntv2ccplayer.h"
9 #include "ntv2devicefeatures.h"
10 #include "ntv2devicescanner.h"
11 #include "ntv2debug.h"
12 #include "ntv2democommon.h"
13 #include "ntv2rp188.h"
14 #include "ntv2transcode.h"
15 #include "ntv2utils.h"
16 #include "ajabase/common/types.h"
19 #include "ajabase/system/process.h"
20 #include "ntv2testpatterngen.h"
24 #include "ajabase/common/common.h"
28 #include "ntv2captionrenderer.h"
29 #include <sstream>
30 #include <fstream>
31 #include <iostream>
32 #include <iomanip>
33 #include <deque>
34 
35 
36 using namespace std;
37 
38 
39 #define AsSCCSource(__x__) reinterpret_cast<SCCSource&>(__x__)
40 #define AsUBytePtr(__x__) reinterpret_cast<UByte*>(__x__)
41 //#define MEASURE_ACCURACY 1 // Enables a feedback mechanism to precisely generate captions at the desired rate
42 
43 static const uint32_t kAppSignature (NTV2_FOURCC('C','C','P','L'));
44 
45 
49 static const string gBuiltInCaptions ("IN CONGRESS, July 4, 1776.\n"
50  "The unanimous Declaration of the thirteen united States of America.\n"
51  "When in the Course of human events, it becomes necessary for one people to dissolve the political bands which have connected them with another, "
52  "and to assume among the powers of the earth, the separate and equal station to which the Laws of Nature and of Nature's God entitle them, a decent "
53  "respect to the opinions of mankind requires that they should declare the causes which impel them to the separation.\n"
54  "We hold these truths to be self-evident, that all men are created equal, that they are endowed by their Creator with certain unalienable Rights, "
55  "that among these are Life, Liberty and the pursuit of Happiness. That to secure these rights, Governments are instituted among Men, deriving their "
56  "just powers from the consent of the governed, That whenever any Form of Government becomes destructive of these ends, it is the Right of the People to alter or to abolish it, "
57  "and to institute new Government, laying its foundation on such principles and organizing its powers in such form, as to them shall seem most likely to effect their Safety and "
58  "Happiness. Prudence, indeed, will dictate that Governments long established should not be changed for light and transient causes; and accordingly all experience hath shewn, "
59  "that mankind are more disposed to suffer, while evils are sufferable, than to right themselves by abolishing the forms to which they are accustomed. "
60  "But when a long train of abuses and usurpations, pursuing invariably the same Object evinces a design to reduce them under absolute Despotism, it is their right, "
61  "it is their duty, to throw off such Government, and to provide new Guards for their future security. Such has been the patient sufferance of these Colonies; and such is now "
62  "the necessity which constrains them to alter their former Systems of Government. The history of the present King of Great Britain is a history of repeated injuries and "
63  "usurpations, all having in direct object the establishment of an absolute Tyranny over these States. To prove this, let Facts be submitted to a candid world.\n"
64  "He has refused his Assent to Laws, the most wholesome and necessary for the public good.\n"
65  "He has forbidden his Governors to pass Laws of immediate and pressing importance, unless suspended in their operation till his Assent should be obtained; "
66  "and when so suspended, he has utterly neglected to attend to them.\n"
67  "He has refused to pass other Laws for the accommodation of large districts of people, unless those people would relinquish the right of Representation in the Legislature, "
68  "a right inestimable to them and formidable to tyrants only.\n"
69  "He has called together legislative bodies at places unusual, uncomfortable, and distant from the depository of their public Records, for the sole purpose of fatiguing them "
70  "into compliance with his measures. \n"
71  "He has dissolved Representative Houses repeatedly, for opposing with manly firmness his invasions on the rights of the people.\n"
72  "He has refused for a long time, after such dissolutions, to cause others to be elected; whereby the Legislative powers, incapable of Annihilation, have returned to the People "
73  "at large for their exercise; the State remaining in the mean time exposed to all the dangers of invasion from without, and convulsions within.\n"
74  "He has endeavoured to prevent the population of these States; for that purpose obstructing the Laws for Naturalization of Foreigners; refusing to pass others to encourage "
75  "their migrations hither, and raising the conditions of new Appropriations of Lands.\n"
76  "He has obstructed the Administration of Justice, by refusing his Assent to Laws for establishing Judiciary powers.\n"
77  "He has made Judges dependent on his Will alone, for the tenure of their offices, and the amount and payment of their salaries.\n"
78  "He has erected a multitude of New Offices, and sent hither swarms of Officers to harrass our people, and eat out their substance.\n"
79  "He has kept among us, in times of peace, Standing Armies without the Consent of our legislatures.\n"
80  "He has affected to render the Military independent of and superior to the Civil power.\n"
81  "He has combined with others to subject us to a jurisdiction foreign to our constitution, and unacknowledged by our laws; "
82  "giving his Assent to their Acts of pretended Legislation:\n"
83  "For Quartering large bodies of armed troops among us:\n"
84  "For protecting them, by a mock Trial, from punishment for any Murders which they should commit on the Inhabitants of these States:\n"
85  "For cutting off our Trade with all parts of the world:\n"
86  "For imposing Taxes on us without our Consent:\n"
87  "For depriving us in many cases, of the benefits of Trial by Jury:\n"
88  "For transporting us beyond Seas to be tried for pretended offences.\n"
89  "For abolishing the free System of English Laws in a neighbouring Province, establishing therein an Arbitrary government, and enlarging its Boundaries so as to render it at "
90  "once an example and fit instrument for introducing the same absolute rule into these Colonies:\n"
91  "For taking away our Charters, abolishing our most valuable Laws, and altering fundamentally the Forms of our Governments:\n"
92  "For suspending our own Legislatures, and declaring themselves invested with power to legislate for us in all cases whatsoever.\n"
93  "He has abdicated Government here, by declaring us out of his Protection and waging War against us.\n"
94  "He has plundered our seas, ravaged our Coasts, burnt our towns, and destroyed the lives of our people.\n"
95  "He is at this time transporting large Armies of foreign Mercenaries to compleat the works of death, desolation and tyranny, already begun with circumstances of Cruelty & "
96  "perfidy scarcely paralleled in the most barbarous ages, and totally unworthy the Head of a civilized nation.\n"
97  "He has constrained our fellow Citizens taken Captive on the high Seas to bear Arms against their Country, to become the executioners of their friends and Brethren, "
98  "or to fall themselves by their Hands.\n"
99  "He has excited domestic insurrections amongst us, and has endeavoured to bring on the inhabitants of our frontiers, the merciless Indian Savages, whose known rule of warfare, "
100  "is an undistinguished destruction of all ages, sexes and conditions.\n"
101  "In every stage of these Oppressions We have Petitioned for Redress in the most humble terms: Our repeated Petitions have been answered only by repeated injury. "
102  "A Prince whose character is thus marked by every act which may define a Tyrant, is unfit to be the ruler of a free people.\n"
103  "Nor have We been wanting in attentions to our Brittish brethren. We have warned them from time to time of attempts by their legislature to extend an unwarrantable "
104  "jurisdiction over us. We have reminded them of the circumstances of our emigration and settlement here. We have appealed to their native justice and magnanimity, "
105  "and we have conjured them by the ties of our common kindred to disavow these usurpations, which, would inevitably interrupt our connections and correspondence. "
106  "They too have been deaf to the voice of justice and of consanguinity. We must, therefore, acquiesce in the necessity, which denounces our Separation, and hold them, "
107  "as we hold the rest of mankind, Enemies in War, in Peace Friends.\n"
108  "We, therefore, the Representatives of the united States of America, in General Congress, Assembled, appealing to the Supreme Judge of the world for the rectitude of "
109  "our intentions, do, in the Name, and by Authority of the good People of these Colonies, solemnly publish and declare, That these United Colonies are, and of Right ought "
110  "to be Free and Independent States; that they are Absolved from all Allegiance to the British Crown, and that all political connection between them and the State of Great "
111  "Britain, is and ought to be totally dissolved; and that as Free and Independent States, they have full Power to levy War, conclude Peace, contract Alliances, establish "
112  "Commerce, and to do all other Acts and Things which Independent States may of right do. And for the support of this Declaration, with a firm reliance on the protection of "
113  "divine Providence, we mutually pledge to each other our Lives, our Fortunes and our sacred Honor.");
114 
118 static istringstream gBuiltInStream (gBuiltInCaptions);
119 
120 #if defined (MEASURE_ACCURACY)
121 
126  class Speedometer
127  {
128  public:
134  Speedometer (const size_t inNumSamples = 20)
135  : mMaxNumSamples (inNumSamples),
136  mSampleCallTally (0)
137  {
138  mTimespanSamples.push_back (10); // Initial seed of 10 millisec
139  mWhenLastSampleCall = AJATime::GetSystemMilliseconds ();
140  }
141 
146  virtual void Sample (void)
147  {
148  if (mTimespanSamples.size () >= mMaxNumSamples)
149  mTimespanSamples.pop_front ();
150  const uint64_t now (AJATime::GetSystemMilliseconds ());
151  mTimespanSamples.push_back (now - mWhenLastSampleCall);
152  mWhenLastSampleCall = now;
153  mSampleCallTally++;
154  }
155 
159  virtual double GetAvgMilliSecsBetweenSamples (void) const
160  {
161  uint64_t sum (0.0);
162  for (SampleQueueConstIter iter (mTimespanSamples.begin ()); iter != mTimespanSamples.end (); ++iter)
163  sum += *iter;
164  return double (sum) / double (mTimespanSamples.size ());
165  }
166 
170  virtual double GetAvgSamplesPerSecond (void) const
171  {
172  uint64_t sum (0.0);
173  for (SampleQueueConstIter iter (mTimespanSamples.begin ()); iter != mTimespanSamples.end (); ++iter)
174  sum += *iter;
175  return double (mTimespanSamples.size ()) * 1000.0 / double (sum);
176  }
177 
178  virtual inline double GetAvgSamplesPerMinute (void) const {return GetAvgSamplesPerSecond () * 60.0;}
179  virtual inline size_t GetSampleCount (void) const {return mTimespanSamples.size ();}
180  virtual inline uint64_t GetSampleCountTally (void) const {return mSampleCallTally;}
181 
182  private:
183  typedef std::deque <uint64_t> SampleQueue;
184  typedef SampleQueue::const_iterator SampleQueueConstIter;
185 
186  SampleQueue mTimespanSamples;
187  const size_t mMaxNumSamples;
188  uint64_t mWhenLastSampleCall;
189  uint64_t mSampleCallTally;
190 
191  }; // Speedometer
192 
193 
200  static ostream & operator << (ostream & inOutStr, const Speedometer & inObj)
201  {
202  const double samplesPerSecond (inObj.GetAvgSamplesPerSecond ());
203  const double samplesPerMinute (samplesPerSecond * 60.0);
204  return inOutStr << samplesPerMinute << " per min";
205  }
206 
207  static uint64_t gWhenLastDisplay (0);
208 
209 #endif // MEASURE_ACCURACY
210 
212 {
213  static const string EndActions[] = {"Quit", "Repeat", "Idle", ""};
214  AJALabelValuePairs result;
215  string filesToPlay(aja::join(fFilesToPlay, "\n"));
216  if (filesToPlay.empty()) filesToPlay = "<default>";
217  AJASystemInfo::append(result, "Files to Play", filesToPlay);
218  AJASystemInfo::append(result, "End Action", EndActions[fEndAction]);
219  AJASystemInfo::append(result, "Caption Mode", ::NTV2Line21ModeToStr(fCaptionMode));
220  AJASystemInfo::append(result, "Caption Channel", ::NTV2Line21ChannelToStr(fCaptionChannel));
221  AJASystemInfo::append(result, "Newlines Make New Rows", fNewLinesAreNewRows ? "Y" : "N");
222  AJASystemInfo::append(result, "Chars Per Minute", aja::to_string(fCharsPerMinute));
223  AJASystemInfo::append(result, "Attributes", ::NTV2Line21AttributesToStr(fAttributes));
224  return result;
225 }
226 
227 AJALabelValuePairs CCPlayerConfig::Get (const bool inCompact) const
228 {
229  AJALabelValuePairs result (PlayerConfig::Get (inCompact));
230  AJASystemInfo::append(result, "Background Pattern", fTestPatternName);
231  AJASystemInfo::append(result, "Emit Statistics", fEmitStats ? "Y" : "N");
232  AJASystemInfo::append(result, "Force RTP", fForceRTP ? (fForceRTP&2 ? "MultiPkt" : "UniPkt") : "Normal");
233  AJASystemInfo::append(result, "Suppress Audio", fSuppressAudio ? "Y" : "N");
234  AJASystemInfo::append(result, "Suppress Line21", fSuppressLine21 ? "Y" : "N");
235  AJASystemInfo::append(result, "Suppress 608 Pkt", fSuppress608 ? "Y" : "N");
236  AJASystemInfo::append(result, "Suppress 708 Pkt", fSuppress708 ? "Y" : "N");
237  AJASystemInfo::append(result, "Suppress Timecode", fSuppressTimecode ? "Y" : "N");
238  for (CaptionChanGenMapCIter it(fCapChanGenConfigs.begin()); it != fCapChanGenConfigs.end(); ++it)
239  {
240  AJASystemInfo::append(result, ::NTV2Line21ChannelToStr(it->first, false));
241  AJALabelValuePairs pairs(it->second.Get());
242  for (AJALabelValuePairsConstIter iter(pairs.begin()); iter != pairs.end(); ++iter)
243  result.push_back(*iter);
244  }
245  return result;
246 }
247 
248 std::ostream & operator << (std::ostream & ioStrm, const CCPlayerConfig & inObj)
249 {
250  return ioStrm << AJASystemInfo::ToString(inObj.Get());
251 }
252 
253 
255 // Caption Source
257 
268 
269 
273 typedef deque <CaptionSourcePtr> CaptionSourceList;
274 typedef CaptionSourceList::const_iterator CaptionSourceListConstIter;
275 
276 
278 {
279  // Instance Methods
280  public:
289  explicit CaptionSource (const double inCharsPerMinute, istream * pInInputStream, const string & inFilePath, const bool inDeleteInputStream = false)
290  : mpInputStream (pInInputStream),
291  mInputFilePath (inFilePath),
292  mCharsPerMinute (inCharsPerMinute),
293  mMaxRowCharWidth (32),
294  mFinished (false),
295  mDeleteInputStream (inDeleteInputStream),
296  mIsTextMode (false),
297  mMilliSecsPerChar (0.0),
298  mCaptionChannel (NTV2_CC608_ChannelInvalid)
299  {
300  NTV2_ASSERT(mpInputStream); // Must be non-NULL pointer
301  NTV2_ASSERT(mCharsPerMinute > 0.0); // Must be greater than zero
302  *mpInputStream >> std::noskipws; // Include whitespace when reading from this stream
303  mMilliSecsPerChar = 60000.0 / mCharsPerMinute; // Milliseconds of delay (sleep time) between emitting successive characters
304  }
305 
306 
311  virtual ~CaptionSource ()
312  {
313  if (mDeleteInputStream && mpInputStream)
314  {
315  delete mpInputStream;
316  mpInputStream = AJA_NULL;
317  }
318  #if defined (MEASURE_ACCURACY)
319  PLDBG(::NTV2Line21ChannelToStr(mCaptionChannel) << ": " << mCharSpeed.GetSampleCountTally() << " final chars: " << mCharSpeed);
320  #endif // MEASURE_ACCURACY
321  }
322 
328  virtual string GetNextCaptionCharacter (void)
329  {
330  static double milliSecsPerChar(mMilliSecsPerChar);
331  string resultChar;
332  unsigned char rawBytes[5] = {0, 0, 0, 0, 0};
333 
334  AJATime::Sleep (int32_t(milliSecsPerChar));
335  if (mpInputStream->tellg() == 0 && !mInputFilePath.empty())
336  PLNOTE("Starting caption file '" << mInputFilePath << "'");
337 
338  *mpInputStream >> rawBytes[0];
339  if (mpInputStream->eof())
340  SetFinished();
341 
342  if (rawBytes[0] < 0x80) // 1-byte code
343  {
344  if (rawBytes[0])
345  resultChar = string (1, char(rawBytes[0]));
346  }
347  else if (rawBytes[0] < 0xC0) // invalid
348  PLWARN(::NTV2Line21ChannelToStr(mCaptionChannel) << ": Invalid UTF8 value read from input stream: " << xHEX0N(uint16_t(rawBytes[0]),2));
349  else if (rawBytes[0] < 0xE0) // 2-byte code
350  {
351  if (IsFinished())
352  PLWARN(::NTV2Line21ChannelToStr(mCaptionChannel) << ": EOF on input stream before reading byte 2 of 2-byte UTF8 character");
353  else
354  {
355  resultChar = char(rawBytes[0]);
356  *mpInputStream >> rawBytes[1];
357  if (mpInputStream->eof())
358  SetFinished ();
359  resultChar += char(rawBytes[1]);
360  NTV2_ASSERT(resultChar.length() == 2);
361  }
362  }
363  else if (rawBytes[0] < 0xF0) // 3-byte code
364  {
365  resultChar = char(rawBytes[0]);
366  for (unsigned ndx(1); ndx <= 2; ndx++)
367  {
368  if (IsFinished())
369  {
370  PLWARN(::NTV2Line21ChannelToStr(mCaptionChannel) << ": EOF on input stream before reading byte " << DEC(ndx + 1) << " of 3-byte UTF8 character");
371  resultChar = "";
372  break;
373  }
374  *mpInputStream >> rawBytes[ndx];
375  if (mpInputStream->eof())
376  SetFinished();
377  resultChar += char(rawBytes[ndx]);
378  }
379  if (!IsFinished()) NTV2_ASSERT(resultChar.length() == 3);
380  }
381  else if (rawBytes[0] < 0xF8) // 4-byte code
382  {
383  resultChar = char(rawBytes[0]);
384  for (unsigned ndx(1); ndx <= 3; ndx++)
385  {
386  if (IsFinished())
387  {
388  PLWARN(::NTV2Line21ChannelToStr(mCaptionChannel) << "; EOF on input stream before reading byte " << DEC(ndx + 1) << " of 4-byte UTF8 character");
389  resultChar = "";
390  break;
391  }
392  *mpInputStream >> rawBytes[ndx];
393  if (mpInputStream->eof())
394  SetFinished();
395  resultChar += char(rawBytes[ndx]);
396  }
397  if (!IsFinished()) NTV2_ASSERT(resultChar.length() == 4);
398  }
399  else
400  PLWARN(::NTV2Line21ChannelToStr(mCaptionChannel) << ": UTF8 byte value not handled: " << xHEX0N(uint16_t(rawBytes[0]),2));
401 
402  #if defined (MEASURE_ACCURACY)
403  if (!resultChar.empty ())
404  mCharSpeed.Sample ();
405 
406  if (AJATime::GetSystemMilliseconds () - gWhenLastDisplay > 1000)
407  {
408  // Once per second, see how far off I am from the target character rate, and adjust the sleep time as needed...
409  const double avg (mCharSpeed.GetAvgMilliSecsBetweenSamples ());
410  const double diff (avg - mMilliSecsPerChar);
411  milliSecsPerChar = milliSecsPerChar - diff;
412  if (milliSecsPerChar < 0.0)
413  milliSecsPerChar = mMilliSecsPerChar;
414  PLDBG(mCharSpeed.GetSampleCountTally() << " " << ::NTV2Line21ChannelToStr(mCaptionChannel)
415  << " chars: " << mCharSpeed << " " << milliSecsPerChar << "ms/Char " << avg << "avg - "
416  << mMilliSecsPerChar << " => " << diff << "diff");
417  gWhenLastDisplay = AJATime::GetSystemMilliseconds ();
418  }
419  #endif // MEASURE_ACCURACY
420 
421  return resultChar;
422 
423  } // GetNextCaptionCharacter
424 
425 
433  virtual string GetNextCaptionWord (bool & outLineBreak)
434  {
435  std::locale loc;
436  string resultWord;
437  string nextChar (GetNextCaptionCharacter ());
438 
439  outLineBreak = false;
440  while (!nextChar.empty ())
441  {
442  if (IsSpaceChar (nextChar) || IsControlChar (nextChar))
443  {
444  outLineBreak = (nextChar.at (0) == '\n' || nextChar.at (0) == '\r');
445  break; // Control chars & whitespace break words (HT, LF, CR, etc.) -- but don't include them in the word
446  }
447 
448  resultWord += nextChar;
449  if (IsWordBreakCharacter (nextChar))
450  break; // Some punctuation breaks word -- include in the word, too
451 
452  nextChar = GetNextCaptionCharacter ();
453  } // loop til break
454 
455  return resultWord;
456 
457  } // GetNextCaptionWord
458 
459 
465  virtual string GetNextCaptionRow (const bool inBreakLinesOnNewLineChars = false)
466  {
467  string resultRow;
468 
469  // Build resultRow one word at a time (except Text Mode)...
470  while (true)
471  {
472  if (mIsTextMode)
473  {
474  // Special case for Text Mode...
475  string nextChar (GetNextCaptionCharacter ());
476  while (!nextChar.empty ())
477  {
478  if (nextChar.at (0) == '\n' || nextChar.at (0) == '\r')
479  return resultRow; // LF and CR will break the row -- but don't include LF/CR in the row text
480 
481  resultRow += nextChar;
482  nextChar = GetNextCaptionCharacter ();
483  } // loop til break
484  return resultRow;
485  } // if Text Mode
486 
487 
488  // Any text left over from the last time?
489  if (!mLeftoverRowText.empty ())
490  {
491  // Use whatever text was left over from the last time...
492  if (mLeftoverRowText.length () > mMaxRowCharWidth)
493  {
494  // Not all of it will fit. Use whatever will fit and save the rest for later...
495  resultRow = mLeftoverRowText.substr (0, mMaxRowCharWidth);
496  mLeftoverRowText.erase (0, mMaxRowCharWidth);
497  break; // Done
498  }
499  else
500  {
501  resultRow = mLeftoverRowText;
502  mLeftoverRowText.clear ();
503  }
504  } // if any leftover text
505 
506  if (resultRow.length () == mMaxRowCharWidth) // Completely full?
507  break; // If so, send it!
508 
509  // ResultRow has room for more.
510  // Get the next word from the caption source...
511  bool lineBreak (false);
512  string nextWord (GetNextCaptionWord (lineBreak));
513  if (nextWord.empty () && IsFinished ())
514  break;
515 
516  if (nextWord.empty () && !lineBreak)
517  continue; // Nothing to add at this time
518 
519  // If there's anything to send, and the word is maxRowWidth or longer, send resultRow now, and save the rest...
520  if (!resultRow.empty () && nextWord.length () >= mMaxRowCharWidth)
521  {
522  mLeftoverRowText = nextWord; // Save the word for next time
523  break; // Send resultRow now
524  }
525 
526  // If the word is longer than maxRowWidth...
527  if (nextWord.length () >= mMaxRowCharWidth)
528  {
529  resultRow = nextWord.substr (0, mMaxRowCharWidth); // Send whatever will fit
530  nextWord.erase (0, mMaxRowCharWidth);
531  mLeftoverRowText = nextWord; // Save the rest for next time
532  break; // Send resultRow now
533  }
534 
535  // Add the word only if it will fit...
536  const size_t newLength ((resultRow.length () ? resultRow.length () + 1 : 0) + nextWord.length ());
537  if (newLength > mMaxRowCharWidth)
538  {
539  // Wrap this word onto next line...
540  mLeftoverRowText = nextWord; // Save the word for next time
541  break; // Send resultRow now
542  }
543 
544  if (resultRow.empty ())
545  resultRow = nextWord;
546  else
547  resultRow += " " + nextWord;
548  if (inBreakLinesOnNewLineChars && lineBreak)
549  break;
550  } // loop til I have a row to return
551 
552  return resultRow;
553 
554  } // GetNextCaptionRow
555 
556 
557  virtual inline bool IsPlainTextSource (void) const {return true;}
558  virtual inline bool IsFinished (void) const {return mFinished;}
559  virtual inline void SetFinished (void) {mFinished = true;}
560  virtual inline void SetCaptionChannel (const NTV2Line21Channel inCCChannel) {mCaptionChannel = inCCChannel;}
561  virtual inline NTV2Line21Channel GetCaptionChannel (void) const {return mCaptionChannel;}
562  virtual inline bool IsF1Channel(void) const {return IsField1Line21CaptionChannel(mCaptionChannel);}
563 
564 
570  virtual inline void SetTextMode (const bool inIsTextMode) {mIsTextMode = inIsTextMode;}
571 
572  // Private Instance Methods
573  private:
574  inline CaptionSource (const CaptionSource & inCaptionSource) : mDeleteInputStream (false) {(void) inCaptionSource;} // Hidden
575  virtual inline CaptionSource & operator = (const CaptionSource & inCaptionSource) {(void) inCaptionSource; return *this;} // Hidden
576 
577 
578  // Instance Data
579  private:
580  istream * mpInputStream;
581  string mInputFilePath;
582  double mCharsPerMinute;
583  string mLeftoverRowText;
584  size_t mMaxRowCharWidth;
585  bool mFinished;
586  const bool mDeleteInputStream;
587  bool mIsTextMode;
588  double mMilliSecsPerChar;
589  NTV2Line21Channel mCaptionChannel;
590  #if defined (MEASURE_ACCURACY)
591  Speedometer mCharSpeed;
592  #endif // MEASURE_ACCURACY
593 
594 
595  // Private Class Methods
596  private:
597  static bool IsWordBreakCharacter (const string & inUTF8Char)
598  {
599  static const string wordBreakCharacters ("!#$%&()*+,./:;<=>?@[\\]^_`{|}~. \t");
600  if (inUTF8Char.length () != 1)
601  return false;
602  return wordBreakCharacters.find (inUTF8Char) != string::npos;
603  }
604 
605  static bool IsSpaceChar (const string & inUTF8Char)
606  {
607  // tab, newline, vertical tab, form feed, carriage return, and space
608  if (inUTF8Char.length () != 1)
609  return false;
610  const unsigned char c = UByte(inUTF8Char[0]);
611  if (c == 0x09 || c == 0x0A || c == 0x0B || c == 0x0C || c == 0x0D || c == 0x20)
612  return true;
613  return false;
614  }
615 
616  static bool IsControlChar (const string & inUTF8Char)
617  {
618  // ASCII characters octal codes 000 through 037, and 177 (DEL)
619  if (inUTF8Char.length () != 1)
620  return false;
621  unsigned char c = UByte(inUTF8Char[0]);
622  if ((c > 0x00 && c < ' ') || c == 0x7F)
623  return true;
624  return false;
625  }
626 
627 }; // CaptionSource
628 
629 
630 class SCCSource : public CaptionSource
631 {
632  public: // PUBLIC INSTANCE METHODS
633  explicit SCCSource (const double inCharsPerMinute, istream * pInInputStream, const string & inFilePath, const bool inDeleteInputStream = false);
634  virtual ~SCCSource ()
635  {
636  }
637  virtual bool IsPlainTextSource (void) const {return false;}
638  virtual bool EnqueueCCDataToFrame (CNTV2CaptionEncoder608Ptr inEncoder, const uint32_t inFrameNum);
639  virtual string GetNextCaptionCharacter (void) {return string();}
640  virtual string GetNextCaptionWord (bool & outLineBreak) {(void) outLineBreak; return string();}
641  virtual string GetNextCaptionRow (const bool inBreakLines = false) {(void) inBreakLines; return string();}
642 
643  private: // PRIVATE INSTANCE METHODS
644  virtual inline SCCSource & operator = (const SCCSource & inCaptionSource) {(void) inCaptionSource; return *this;} // Hidden
645 
646  private: // PRIVATE INSTANCE DATA
647  typedef std::vector<uint16_t> UWords;
648  typedef UWords::const_iterator UWordsConstIter;
649  typedef std::map<uint32_t,UWords> CCDataMap; // Mapping: starting frame# to list of CCData words
650  typedef CCDataMap::const_iterator CCDataMapConstIter;
651 
652  CCDataMap mCCDataMap;
653  CCDataMapConstIter mCCDataMapIter;
654  size_t mLastCCDataWordNdx;
655  uint32_t mMaxFrameNum;
656 }; // SCCSource
657 
658 
659 
660 SCCSource::SCCSource (const double inCharsPerMinute, istream * pInInputStream, const string & inFilePath, const bool inDeleteInputStream)
661  : CaptionSource(inCharsPerMinute, pInInputStream, inFilePath, inDeleteInputStream),
662  mLastCCDataWordNdx (0),
663  mMaxFrameNum (0)
664 {
665  NTV2StringList lines;
666  while (!pInInputStream->fail())
667  {
668  string line;
669  std::getline(*pInInputStream, line);
670  aja::strip(line);
671  if (!line.empty())
672  lines.push_back(line);
673  }
674  NTV2StringListConstIter iter(lines.begin());
675  if (iter == lines.end())
676  {PLFAIL("No lines!"); return;}
677  if (iter->find("Scenarist_SCC") == string::npos)
678  {PLFAIL("No 'Scenarist_SCC' heading!"); return;}
679 
680  AJATimeCode tc;
681  const AJATimeBase timeBase (CNTV2DemoCommon::GetAJAFrameRate(NTV2_FRAMERATE_5994)); // For now, since CEA608 focused
682  const bool isDropFrame (true); // For now, since CEA608 focused
683  while (++iter != lines.end())
684  {
685  const string & line(*iter);
686  if (line.empty())
687  continue; // empty line
688  const size_t tabPos(line.find('\t'));
689  if (tabPos == string::npos)
690  continue; // no tab character
691 
692  // Split line at tab
693  const NTV2StringList tabChunks (aja::split(line, '\t'));
694  NTV2_ASSERT(tabChunks.size() > 1);
695 
696  // Parse timecode
697  string timecodeChunk(tabChunks.at(0));
698  aja::strip(timecodeChunk);
699  const NTV2StringList tcPieces(aja::split(timecodeChunk, ':'));
700  if (tcPieces.size() < 4)
701  {PLWARN(tcPieces.size() << " timecode components separated by ':' fewer than 4"); continue;}
702  const uint32_t tcComponents[4] = { uint32_t(aja::stoul(tcPieces[0])), uint32_t(aja::stoul(tcPieces[1])),
703  uint32_t(aja::stoul(tcPieces[2])), uint32_t(aja::stoul(tcPieces[3])) };
704  tc.SetHmsf(tcComponents[0], tcComponents[1], tcComponents[2], tcComponents[3], timeBase, isDropFrame);
705 
706  // Parse UWords
707  UWords ccWords;
708  string ccDataChunk(tabChunks.at(1));
709  aja::strip(ccDataChunk);
710  const NTV2StringList ccDataPieces(aja::split(ccDataChunk, ' '));
711  for (NTV2StringListConstIter it(ccDataPieces.begin()); it != ccDataPieces.end(); ++it)
712  {
713  string ccDataWord(*it);
714  aja::strip(ccDataWord);
715  if (ccDataWord.find("0x") == string::npos && ccDataWord.find("0X") == string::npos)
716  ccDataWord = "0x" + ccDataWord;
717  const uint16_t ccWord(UWord(aja::stoul(ccDataWord, AJA_NULL, 16)));
718  ccWords.push_back(ccWord);
719  }
720 
721  mMaxFrameNum = tc.QueryFrame();
722  CCDataMapConstIter iter(mCCDataMap.find(mMaxFrameNum));
723  if (iter != mCCDataMap.end())
724  PLWARN("Frame " << mMaxFrameNum << " already present, has " << iter->second.size() << " byte pairs");
725  else
726  mCCDataMap[mMaxFrameNum] = ccWords;
727  PLDBG("Frame " << tc.QueryFrame() << " has " << ccWords.size() << " CC byte pairs");
728  mCCDataMapIter = mCCDataMap.begin();
729  mLastCCDataWordNdx = 0;
730  } // for each line
731  if (!mCCDataMap.empty())
732  PLINFO("SCC data frames " << mCCDataMap.begin()->first << " thru " << mMaxFrameNum << ", size=" << mCCDataMap.size());
733 }
734 
735 bool SCCSource::EnqueueCCDataToFrame (CNTV2CaptionEncoder608Ptr inEncoder, const uint32_t inPlayFrame)
736 {
737  bool result(false);
738  uint32_t playFrame(mMaxFrameNum ? inPlayFrame % (mMaxFrameNum + 1) : inPlayFrame);
739  if (!inEncoder)
740  return result;
741  if (mCCDataMapIter != mCCDataMap.end() && mLastCCDataWordNdx < mCCDataMapIter->second.size())
742  {
743  uint32_t CCFrame(mCCDataMapIter->first);
744  if (CCFrame > playFrame) // CCFrame ahead of playout frame?
745  {
746  if (CCFrame == mMaxFrameNum)
747  playFrame = CCFrame; // This prevents "sticking" on last frame -- force last CC bytes out
748  else
749  {
750  const uint32_t delayFrames(CCFrame - playFrame);
751  PLINFO("CCFrame " << DEC(CCFrame) << " > playFrame " << DEC(playFrame) << "|" << DEC(inPlayFrame) << ", delaying " << DEC(delayFrames) << " frames");
752  result = true; // inEncoder->EnqueueDelay(delayFrames, GetCaptionChannel());
753  AJATime::Sleep(delayFrames * 1000 / 30);
754  playFrame += delayFrames;
755  }
756  }
757  if (CCFrame <= playFrame) // If current CCFrame at or behind playFrame...
758  { // ...then enqueue CCFrame's CCBytes
759  PLINFO("CCFrame " << DEC(CCFrame) << " <= playFrame " << DEC(playFrame) << "|" << DEC(inPlayFrame) << ": " << mCCDataMapIter->second);
760  do
761  {
762  const uint16_t ccWord(mCCDataMapIter->second.at(mLastCCDataWordNdx));
763  const UByte cc1(UByte(ccWord >> 8));
764  const UByte cc2(UByte(ccWord & 0x00FF));
765  CaptionData ccData;
766  if (IsF1Channel()) {ccData.f1_char1 = cc1; ccData.f1_char2 = cc2; ccData.bGotField1Data = true;}
767  else {ccData.f2_char1 = cc1; ccData.f2_char2 = cc2; ccData.bGotField2Data = true;}
768 
769  result = inEncoder->EnqueueCaptionData(ccData);
770  if (++mLastCCDataWordNdx >= mCCDataMapIter->second.size())
771  {
772  mLastCCDataWordNdx = 0;
773  ++mCCDataMapIter;
774  if (mCCDataMapIter == mCCDataMap.end())
775  {
776  SetFinished();
777  PLINFO("Finished at playFrame " << DEC(playFrame) << "|" << DEC(inPlayFrame));
778  break; // Exit do/while loop
779  }
780  }
781  } while (mCCDataMapIter->first == CCFrame);
782  } // if CCFrame at or behind playFrame
783  }
784  return result;
785 }
786 
795 static CaptionSourceList GetCaptionSources (const NTV2StringList & inFilesToPlay, const double inCharsPerMinute)
796 {
797  CaptionSourceList result;
798  static istream * pStdIn (&cin);
799  static size_t nFilesToPlay (9999);
800 
801  if (nFilesToPlay == 9999)
802  nFilesToPlay = inFilesToPlay.size();
803 
804  if (nFilesToPlay == 0)
805  {
806  if (gBuiltInStream.eof())
807  {
808  // The built-in caption stream has already been used.
809  // This can happen when running in "loop" mode, so reset it, so it can be used again...
810  gBuiltInStream.clear(); // Clear EOF
811  gBuiltInStream.seekg(0); // Rewind
812  }
813  result.push_back(CaptionSourcePtr(new CaptionSource(inCharsPerMinute, &gBuiltInStream, string())));
814  }
815  else
816  {
817  for (size_t ndx(0); ndx < inFilesToPlay.size(); ndx++)
818  {
819  const string filePath(inFilesToPlay.at(ndx));
820  if (filePath == "-")
821  {
822  if (pStdIn)
823  { // Add stdin once
824  result.push_back(CaptionSourcePtr(new CaptionSource(inCharsPerMinute, pStdIn, string())));
825  pStdIn = AJA_NULL; // Standard input can only be read from once
826  }
827  else
828  cerr << "## WARNING: Standard input ('-') can only be specified once" << endl;
829  } // '-' means "read from standard input"
830  else
831  {
832  ifstream * pFileStream (new ifstream(filePath.c_str()));
833  NTV2_ASSERT(pFileStream);
834  if (pFileStream->is_open())
835  {
836  static const string scc(".scc");
837  const size_t pos (filePath.rfind(scc));
838  if (pos == (filePath.length()-scc.length()))
839  result.push_back(CaptionSourcePtr(new SCCSource(inCharsPerMinute, pFileStream, filePath, true)));
840  else
841  result.push_back(CaptionSourcePtr(new CaptionSource(inCharsPerMinute, pFileStream, filePath, true)));
842  PLINFO("Caption file '" << filePath << "' opened");
843  }
844  else
845  {
846  PLWARN("Cannot open caption file '" << filePath << "'");
847  cerr << "## WARNING: Cannot play '" << filePath << "'" << endl;
848  }
849  } // else not '-'
850  } // for each caption file to play
851  } // else caption file list is not empty
852 
853  return result;
854 
855 } // GetCaptionSources
856 
857 
858 
860  : mConfig (inConfigData),
861  mPlayThread (),
862  mGeneratorThreads (),
863  mDeviceID (DEVICE_ID_NOTFOUND),
864  mSavedTaskMode (NTV2_DISABLE_TASKS),
865  mVideoStandard (NTV2_STANDARD_INVALID),
866  mPlayerQuit (false),
867  mCaptionGeneratorQuit (false),
868  mActiveFrameStores (),
869  mConnections ()
870 {
871  NTV2_ASSERT(!mConfig.fCapChanGenConfigs.empty());
872  mGeneratorThreads.resize(size_t(NTV2_CC608_XDS));
873  while (mGeneratorThreads.size() < size_t(NTV2_CC608_XDS))
874  mGeneratorThreads.push_back(AJAThread());
875 } // constructor
876 
877 
879 {
880  // Stop my playout and producer threads, then destroy them...
881  Quit();
882 
883  mDevice.UnsubscribeOutputVerticalEvent(mActiveFrameStores);
884  if (!mConfig.fDoMultiFormat)
885  {
886  mDevice.SetEveryFrameServices(mSavedTaskMode); // Restore prior service level
887  mDevice.ReleaseStreamForApplication (kAppSignature, int32_t(AJAProcess::GetPid())); // Release the device
888  }
889 
890 } // destructor
891 
892 
893 void NTV2CCPlayer::Quit (const bool inQuitImmediately)
894 {
895  // Kill the caption generators first...
896  mCaptionGeneratorQuit = true;
897  while (!mGeneratorThreads.empty())
898  {
899  while (mGeneratorThreads.back().Active())
900  AJATime::Sleep(10);
901  mGeneratorThreads.pop_back();
902  }
903 
904  if (m608Encoder)
905  {
906  if (inQuitImmediately)
907  {
908  PLDBG("Quit immediate -- flushing");
909  m608Encoder->Flush(); // Immediately flush all queued messages
910  }
911  else
912  {
913  PLDBG("Quit non-immediate -- waiting for queue to drain");
914  while (m608Encoder->GetQueuedByteCount(NTV2_CC608_Field1) || m608Encoder->GetQueuedByteCount(NTV2_CC608_Field2))
915  AJATime::Sleep(10); // Wait for PlayThread encoder's message queues to drain as PlayThread continues
916  // This Sleep isn't necessary, but if not done, the last captions (or Erase) won't get a chance to be seen on downstream
917  // devices (because the AJA device will get released, and the retail services will change the device configuration).
918  AJATime::Sleep(2000);
919  }
920  }
921 
922  mPlayerQuit = true;
923  while (mPlayThread.Active())
924  AJATime::Sleep(10);
925  mDevice.RemoveConnections(mConnections);
926 
927 } // Quit
928 
929 
931 {
932  UWord majorVersion (0), minorVersion (0), pointVersion (0), buildNumber (0);
933  mDevice.GetDriverVersionComponents (majorVersion, minorVersion, pointVersion, buildNumber);
934  // Device Anc extraction requires driver version 12.3 minimum (or 0.0.0.0 for internal development)...
935  if ((majorVersion == 12 && minorVersion >= 3) || (majorVersion >= 13) || (majorVersion == 0 && minorVersion == 0 && pointVersion == 0 && buildNumber == 0))
936  // The device must also support it...
937  if (mDevice.features().CanDoCustomAnc())
938  // And perhaps even do firmware version/date checks??
939  return true;
940  return false;
941 }
942 
943 
945 {
946  AJAStatus status (AJA_STATUS_SUCCESS);
947  CNTV2DemoCommon::SetDefaultPageSize(); // Set host-specific page size
948 
949  // Any AJA devices out there?
951  {cerr << "## ERROR: Device '" << mConfig.fDeviceSpec << "' not found" << endl; return AJA_STATUS_OPEN;}
952  mDeviceID = mDevice.GetDeviceID(); // Keep this ID handy -- it's used frequently
953 
954  if (!mDevice.IsDeviceReady(false))
955  {cerr << "## ERROR: Device '" << mConfig.fDeviceSpec << "' not ready" << endl; return AJA_STATUS_INITIALIZE;}
956  if (!mDevice.features().CanDoPlayback())
957  {cerr << "## ERROR: '" << mDevice.GetDisplayName() << "' is capture-only" << endl; return AJA_STATUS_FEATURE;}
958 
959  if (!mConfig.fDoMultiFormat)
960  {
962  {
963  cerr << "## ERROR: Cannot acquire '" << mDevice.GetDisplayName() << "' because another app owns it" << endl;
964  return AJA_STATUS_BUSY; // Some other app owns the device
965  }
966  mDevice.GetEveryFrameServices(mSavedTaskMode); // Save the current task mode
967  }
968  mDevice.SetEveryFrameServices(NTV2_OEM_TASKS); // Set OEM service level
969 
970 #if defined(_DEBUG)
971  if (mConfig.fForceRTP & BIT(2))
972  { // Hack -- force device to pretend it's a KonaIP2110
973  NTV2Buffer pDevice (&mDevice, sizeof(CNTV2Card));
974  ULWordSequence U32s (pDevice.GetU32s(0, pDevice.GetByteCount()/sizeof(uint32_t)));
975  for (unsigned ndx(0); ndx < U32s.size(); ndx++)
976  if (U32s.at(ndx) == ULWord(mDeviceID))
977  { // by patching its _boardID member...
978  mDeviceID = DEVICE_ID_KONAIP_2110;
979  U32s[ndx] = ULWord(mDeviceID);
980  pDevice.PutU32s(U32s);
981  break;
982  }
983  }
984 #endif // defined(_DEBUG)
985 
986  if (mDevice.features().CanDoMultiFormat() && mConfig.fDoMultiFormat)
987  mDevice.SetMultiFormatMode(true);
988  else if (mDevice.features().CanDoMultiFormat())
989  mDevice.SetMultiFormatMode(false);
990 
991  if (NTV2_IS_VANCMODE_OFF(mConfig.fVancMode)) // if user didn't use --vanc option...
992  if (!DeviceAncExtractorIsAvailable()) // and anc extractor isn't available...
993  mConfig.fVancMode = NTV2_VANCMODE_TALLER; // then enable Vanc anyway
994 
995  // Set up the device video config...
996  status = SetUpOutputVideo();
997  if (AJA_FAILURE(status))
998  return status;
999 
1000  // Set up my background pattern buffer...
1001  status = SetUpBackgroundPatternBuffer();
1002  if (AJA_FAILURE(status))
1003  return status;
1004 
1005  // Set up device signal routing...
1006  status = RouteOutputSignal();
1007  if (AJA_FAILURE(status))
1008  return status;
1009 
1010  #if defined(_DEBUG)
1011  cerr << mConfig << endl;
1012  #endif // defined(_DEBUG)
1013  return AJA_STATUS_SUCCESS;
1014 
1015 } // Init
1016 
1017 
1019 {
1020  // Generate the test pattern...
1021  NTV2TestPatternGen testPatternGen;
1022  const NTV2FormatDescriptor formatDesc (mConfig.fVideoFormat, mConfig.fPixelFormat, mConfig.fVancMode);
1023  testPatternGen.setVANCToLegalBlack(formatDesc.IsVANC()); // Clear the VANC region to legal black if needed
1024 
1025  // Allocate and clear the host video buffer memory...
1026  mVideoBuffer.Allocate(formatDesc.GetVideoWriteSize());
1027 
1028  if (!testPatternGen.DrawTestPattern (mConfig.fTestPatternName, formatDesc, mVideoBuffer))
1029  {
1030  cerr << "## ERROR: DrawTestPattern failed, formatDesc: " << formatDesc << endl;
1031  return AJA_STATUS_FAIL;
1032  }
1033 
1034  // Burn static info into the test pattern...
1035  const string strVideoFormat (CNTV2DemoCommon::StripFormatString (::NTV2VideoFormatToString(mConfig.fVideoFormat)));
1036  { ostringstream oss;
1037  oss << setw(32) << left << string("CCPlayer ") + strVideoFormat + string(formatDesc.IsVANC() ? " VANC" : "");
1038  CNTV2CaptionRenderer::BurnString (oss.str(), NTV2Line21Attributes(NTV2_CC608_White, NTV2_CC608_Cyan), mVideoBuffer, formatDesc, 1, 1); // R1C1
1039  }
1040  { ostringstream oss;
1041  oss << formatDesc.GetRasterWidth() << "Wx" << formatDesc.GetFullRasterHeight() << "H "
1042  << ::NTV2FrameBufferFormatToString(mConfig.fPixelFormat, true) << string(20, ' ');
1043  CNTV2CaptionRenderer::BurnString (oss.str(), NTV2Line21Attributes(NTV2_CC608_White, NTV2_CC608_Cyan), mVideoBuffer, formatDesc, 2, 1); // R2C1
1044  }
1045  return AJA_STATUS_SUCCESS;
1046 
1047 } // SetUpBackgroundPatternBuffer
1048 
1049 
1051 {
1052  // Preflight checks...
1053  if (mDevice.features().GetNumVideoOutputs() < 1)
1054  {cerr << "## ERROR: Device cannot playout" << endl; return AJA_STATUS_UNSUPPORTED;}
1055  if ((mConfig.fOutputChannel == NTV2_CHANNEL1) && !mDevice.features().CanDoFrameStore1Display())
1056  {cerr << "## ERROR: Device cannot playout thru FrameStore 1" << endl; return AJA_STATUS_UNSUPPORTED;}
1057  if (!NTV2_OUTPUT_DEST_IS_SDI(mConfig.fOutputDest))
1058  {
1059  cerr << "## ERROR: CCPlayer uses SDI only, not '" << ::NTV2OutputDestinationToString(mConfig.fOutputDest,true) << "'" << endl;
1060  return AJA_STATUS_UNSUPPORTED;
1061  }
1062  if (!mDevice.features().CanDoOutputDestination(mConfig.fOutputDest))
1063  {
1064  cerr << "## ERROR: No such output connector '" << ::NTV2OutputDestinationToString(mConfig.fOutputDest,true) << "'" << endl;
1065  return AJA_STATUS_UNSUPPORTED;
1066  }
1068  {
1069  if (!mConfig.fDoTsiRouting && mConfig.fOutputChannel != NTV2_CHANNEL1 && mConfig.fOutputChannel != NTV2_CHANNEL5)
1070  {
1071  cerr << "## ERROR: Quad-frame format must use Ch1|Ch5, not '" << ::NTV2ChannelToString(mConfig.fOutputChannel, true) << "'" << endl;
1072  return AJA_STATUS_BAD_PARAM;
1073  }
1074  else if (mConfig.fDoTsiRouting && (mConfig.fOutputChannel & 1))
1075  {
1076  cerr << "## ERROR: UHD/4K TSI must use Ch[1|3|5|7], not '" << ::NTV2ChannelToString(mConfig.fOutputChannel, true) << "'" << endl;
1077  return AJA_STATUS_BAD_PARAM;
1078  }
1079  const NTV2Channel sdiChan(::NTV2OutputDestinationToChannel(mConfig.fOutputDest));
1080  if (!mConfig.fDoTsiRouting && sdiChan != NTV2_CHANNEL1 && sdiChan != NTV2_CHANNEL5)
1081  {
1082  cerr << "## ERROR: UHD/4K Squares must use SDIOut[1|5], not '" << ::NTV2ChannelToString(mConfig.fOutputChannel, true) << "'" << endl;
1083  return AJA_STATUS_BAD_PARAM;
1084  }
1085  else if (mConfig.fDoTsiRouting && (sdiChan & 1))
1086  {
1087  cerr << "## ERROR: UHD/4K TSI must use SDIOut[1|3|5|7], not '" << ::NTV2ChannelToString(mConfig.fOutputChannel, true) << "'" << endl;
1088  return AJA_STATUS_BAD_PARAM;
1089  }
1090  }
1091  else
1092  mConfig.fDoTsiRouting = false; // Allows RouteOutputSignal to cheat
1094  {cerr << "## ERROR: CCPlayer doesn't yet support UHD2/8K formats" << endl; return AJA_STATUS_UNSUPPORTED;}
1095  if (NTV2_IS_625_FORMAT(mConfig.fVideoFormat))
1096  cerr << "## WARNING: SD 625/PAL not supported -- but will insert CEA608 caption packets anyway" << endl;
1098  if (NTV2_IS_VANCMODE_ON(mConfig.fVancMode))
1099  {cerr << "## ERROR: Cannot use VANC mode with UHD/4K/UHD2/8K formats" << endl; return AJA_STATUS_UNSUPPORTED;}
1100  if (NTV2_IS_SD_VIDEO_FORMAT(mConfig.fVideoFormat) && !mConfig.fSuppressLine21)
1102  {cerr << "## ERROR: SD/line21 in " << ::NTV2FrameBufferFormatToString(mConfig.fPixelFormat) << "' not '2vuy'|'v210'" << endl; return AJA_STATUS_UNSUPPORTED;}
1103  if (UWord(mConfig.fOutputChannel) >= mDevice.features().GetNumFrameStores())
1104  {cerr << "## ERROR: Device has " << DEC(mDevice.features().GetNumFrameStores()) << " FrameStore(s), no channel " << DEC(mConfig.fOutputChannel+1) << endl; return AJA_STATUS_UNSUPPORTED;}
1105 
1106  const NTV2FrameRate frameRate(::GetNTV2FrameRateFromVideoFormat(mConfig.fVideoFormat));
1107  if (!NTV2_IS_SD_VIDEO_FORMAT(mConfig.fVideoFormat) && !mConfig.fSuppress708)
1108  if (frameRate == NTV2_FRAMERATE_2500 || frameRate == NTV2_FRAMERATE_5000)
1109  {cerr << "## ERROR: CEA708 CDPs can't accommodate CEA608 captions for " << ::NTV2FrameRateToString(frameRate) << endl; return AJA_STATUS_UNSUPPORTED;}
1110 
1111  //
1112  // Enable the required framestore(s)...
1113  //
1115  mActiveFrameStores = ::NTV2MakeChannelSet(mConfig.fOutputChannel, mConfig.fDoTsiRouting ? 2 : 4);
1116  else
1117  mActiveFrameStores.insert(mConfig.fOutputChannel);
1118  mDevice.EnableChannels (mActiveFrameStores,
1119  !mConfig.fDoMultiFormat); // Disable other channels if not MultiFormat mode
1120 
1121  //
1122  // Set video format/standard...
1123  //
1124  if (!mDevice.features().CanDoVideoFormat(mConfig.fVideoFormat))
1125  {cerr << "## ERROR: '" << ::NTV2VideoFormatToString(mConfig.fVideoFormat) << "' not supported" << endl; return AJA_STATUS_UNSUPPORTED;}
1126  mVideoStandard = ::GetNTV2StandardFromVideoFormat(mConfig.fVideoFormat);
1127  mDevice.SetVideoFormat (mActiveFrameStores, mConfig.fVideoFormat, AJA_RETAIL_DEFAULT);
1129  {}
1130  else if (mConfig.fDoTsiRouting)
1131  mDevice.SetTsiFrameEnable(true, mConfig.fOutputChannel);
1132  else
1133  mDevice.Set4kSquaresEnable(true, mConfig.fOutputChannel);
1134 
1135  //
1136  // Set frame buffer pixel format...
1137  //
1138  if (!mDevice.features().CanDoFrameBufferFormat (mConfig.fPixelFormat))
1139  {cerr << "## ERROR: '" << ::NTV2FrameBufferFormatToString(mConfig.fPixelFormat) << "' not supported" << endl; return AJA_STATUS_UNSUPPORTED;}
1140  if (NTV2_IS_VANCMODE_ON(mConfig.fVancMode) && ::IsRGBFormat(mConfig.fPixelFormat) != mConfig.fDoRGBOnWire)
1141  {cerr << "## ERROR: Routing thru CSC may corrupt VANC in frame buffer" << endl; return AJA_STATUS_UNSUPPORTED;}
1142  mDevice.SetFrameBufferFormat (mActiveFrameStores, mConfig.fPixelFormat);
1143  if (NTV2_IS_VANCMODE_OFF(mConfig.fVancMode))
1144  if (mConfig.fOutputChannel != ::NTV2OutputDestinationToChannel(mConfig.fOutputDest))
1145  {
1146  cerr << "## ERROR: FrameStore" << DEC(mConfig.fOutputChannel+1)
1147  << " doesn't correlate with SDIOut" << DEC(::NTV2OutputDestinationToChannel(mConfig.fOutputDest)+1)
1148  << " -- Anc inserter requires both to match, output signal won't have captions" << endl;
1149  return AJA_STATUS_FAIL;
1150  }
1151 
1152  //
1153  // Enable VANC only if device has no Anc inserters, or if --vanc specified...
1154  //
1157  mDevice.SetVANCMode (mActiveFrameStores, mConfig.fVancMode);
1159  if (NTV2_IS_VANCMODE_ON(mConfig.fVancMode))
1160  if (::Is8BitFrameBufferFormat(mConfig.fPixelFormat))
1161  mDevice.SetVANCShiftMode (mConfig.fOutputChannel, NTV2_VANCDATA_8BITSHIFT_ENABLE); // 8-bit FBFs require VANC bit shift
1162 
1163  //
1164  // Create the caption encoders...
1165  //
1166  if (!CNTV2CaptionEncoder608::Create(m608Encoder))
1167  {cerr << "## ERROR: Cannot create 608 encoder" << endl; return AJA_STATUS_MEMORY;}
1168  if (!CNTV2CaptionEncoder708::Create(m708Encoder))
1169  {cerr << "## ERROR: Cannot create 708 encoder" << endl; return AJA_STATUS_MEMORY;}
1170 
1171  mDevice.SetReference (mDevice.features().CanDo2110() ? NTV2_REFERENCE_SFP1_PTP : NTV2_REFERENCE_FREERUN);
1172 
1173  //
1174  // Subscribe to the output interrupt(s)...
1175  //
1176  mDevice.SubscribeOutputVerticalEvent(mActiveFrameStores);
1177 
1178  cerr << "## NOTE: Generating '" << ::NTV2VideoFormatToString(mConfig.fVideoFormat)
1179  << "' using " << (NTV2_IS_VANCMODE_ON(mConfig.fVancMode) ? "VANC" : "device Anc inserter")
1180  << " on '" << mDevice.GetDisplayName() << "' to " << ::NTV2OutputDestinationToString(mConfig.fOutputDest)
1181  << (mConfig.fDoRGBOnWire ? " (DL-RGB)" : "")
1182  << " from FrameStore" << DEC(mConfig.fOutputChannel+1)
1183  << " using " << ::NTV2FrameBufferFormatToString(mConfig.fPixelFormat) << endl;
1184  return AJA_STATUS_SUCCESS;
1185 
1186 } // SetUpOutputVideo
1187 
1188 
1190 {
1191  const bool isRGBFBF (::IsRGBFormat(mConfig.fPixelFormat));
1192  const bool isRGBWire (mConfig.fDoRGBOnWire); // RGB-over-SDI?
1193  const bool isQuadFmt (NTV2_IS_QUAD_FRAME_FORMAT(mConfig.fVideoFormat));
1194  const bool is4KHFR (NTV2_IS_HFR_STANDARD(mVideoStandard));
1195  const NTV2Channel sdiOutput (::NTV2OutputDestinationToChannel(mConfig.fOutputDest));
1196  NTV2ChannelSet sdiOuts (::NTV2MakeChannelSet(sdiOutput, UWord(mActiveFrameStores.size())));
1197  NTV2ChannelList sdiOutputs (::NTV2MakeChannelList(sdiOuts));
1198  NTV2ChannelList frameStores (::NTV2MakeChannelList(mActiveFrameStores));
1199  NTV2ChannelList tsiMuxes, cscs;
1200  mConnections.clear();
1201 
1202  // Does device have RGB conversion capability for the desired channel?
1203  if (isRGBFBF != isRGBWire // if any CSC(s) are needed
1204  && UWord(mConfig.fOutputChannel) > mDevice.features().GetNumCSCs())
1205  {cerr << "## ERROR: No CSC for channel " << (mConfig.fOutputChannel+1) << endl; return AJA_STATUS_UNSUPPORTED;}
1206  //*UNCOMMENT TO SHOW ROUTING PROGRESS WHILE DEBUGGING*/mDevice.ClearRouting();
1207 
1208  mDevice.SetSDITransmitEnable(sdiOuts, true);
1209  if (isRGBFBF && isRGBWire)
1210  {
1211  if (!mConfig.fDoTsiRouting) // RGBFrameStore ==> DLOut ==> SDIOut
1212  for (size_t ndx(0); ndx < sdiOutputs.size(); ndx++)
1213  { NTV2Channel frmSt(frameStores.at(ndx)), sdiOut(sdiOutputs.at(ndx));
1214  mConnections.insert(NTV2XptConnection(::GetSDIOutputInputXpt(sdiOut, /*isDS2*/false), ::GetDLOutOutputXptFromChannel(sdiOut, /*isDS2*/false)));
1215  mConnections.insert(NTV2XptConnection(::GetSDIOutputInputXpt(sdiOut, /*isDS2*/true), ::GetDLOutOutputXptFromChannel(sdiOut, /*isDS2*/true)));
1216  mConnections.insert(NTV2XptConnection(::GetDLOutInputXptFromChannel(sdiOut), ::GetFrameBufferOutputXptFromChannel(frmSt, true/*isRGB*/, false/*is425*/)));
1217  //*UNCOMMENT TO SHOW ROUTING PROGRESS WHILE DEBUGGING*/mDevice.ApplySignalRoute(mConnections);
1218  // Disable SDI output conversions
1219  mDevice.SetSDIOutLevelAtoLevelBConversion(sdiOut, false);
1220  mDevice.SetSDIOutRGBLevelAConversion(sdiOut, false);
1221  }
1222  else
1223  { // RGBFrameStore ==> 425MUX ==> 2x DLOut ==> 2x SDIOut
1224  sdiOuts = ::NTV2MakeChannelSet(sdiOutput, UWord(2*mActiveFrameStores.size()));
1225  sdiOutputs = ::NTV2MakeChannelList(sdiOuts);
1226  tsiMuxes = CNTV2DemoCommon::GetTSIMuxesForFrameStore(mDevice, frameStores.at(0), UWord(frameStores.size()*2));
1227  mDevice.SetSDITransmitEnable(sdiOuts, true); // Gotta do this again, since sdiOuts changed
1228  for (size_t ndx(0); ndx < sdiOutputs.size(); ndx++)
1229  { NTV2Channel frmSt(frameStores.at(ndx/2)), tsiMux(tsiMuxes.at(ndx/2)), sdiOut(sdiOutputs.at(ndx));
1230  mConnections.insert(NTV2XptConnection(::GetSDIOutputInputXpt(sdiOut, /*isDS2*/false), ::GetDLOutOutputXptFromChannel(sdiOut, /*isDS2*/false)));
1231  mConnections.insert(NTV2XptConnection(::GetSDIOutputInputXpt(sdiOut, /*isDS2*/true), ::GetDLOutOutputXptFromChannel(sdiOut, /*isDS2*/true)));
1232  mConnections.insert(NTV2XptConnection(::GetDLOutInputXptFromChannel(sdiOut), ::GetTSIMuxOutputXptFromChannel(tsiMux, /*isLinkB*/(ndx & 1) > 0, /*isRGB*/true)));
1233  mConnections.insert(NTV2XptConnection(::GetTSIMuxInputXptFromChannel(tsiMux,/*linkB?*/false), ::GetFrameBufferOutputXptFromChannel(frmSt, true/*isRGB*/, false/*is425*/)));
1234  mConnections.insert(NTV2XptConnection(::GetTSIMuxInputXptFromChannel(tsiMux,/*linkB?*/true), ::GetFrameBufferOutputXptFromChannel(frmSt, true/*isRGB*/, true/*is425*/)));
1235  //*UNCOMMENT TO SHOW ROUTING PROGRESS WHILE DEBUGGING*/mDevice.ApplySignalRoute(mConnections);
1236  }
1237  }
1238  }
1239  else if (isRGBFBF && !isRGBWire)
1240  {
1241  if (!mConfig.fDoTsiRouting) // RGBFrameStore ==> CSC ==> SDIOut
1242  for (size_t ndx(0); ndx < sdiOutputs.size(); ndx++)
1243  { NTV2Channel frmSt(frameStores.at(ndx)), sdiOut(sdiOutputs.at(ndx));
1244  mConnections.insert(NTV2XptConnection(::GetCSCInputXptFromChannel(frmSt),
1245  ::GetFrameBufferOutputXptFromChannel(frmSt, /*isRGB*/true, /*is425*/false)));
1246  mConnections.insert(NTV2XptConnection(::GetSDIOutputInputXpt(sdiOut),
1247  ::GetCSCOutputXptFromChannel(frmSt)));
1248  //*UNCOMMENT TO SHOW ROUTING PROGRESS WHILE DEBUGGING*/mDevice.ApplySignalRoute(mConnections);
1249  // Disable SDI output conversions
1250  mDevice.SetSDIOutLevelAtoLevelBConversion(sdiOut, false);
1251  mDevice.SetSDIOutRGBLevelAConversion(sdiOut, false);
1252  }
1253  else
1254  { // TSI // RGBFrameStore ==> 425MUX ==> LFR: 2 x CSC ==> 2 x SDIOut HFR: 4 x CSC ==> 4 x SDI
1255  sdiOuts = ::NTV2MakeChannelSet(sdiOutput, is4KHFR ? 4 : UWord(mActiveFrameStores.size()));
1256  sdiOutputs = ::NTV2MakeChannelList(sdiOuts);
1257  tsiMuxes = CNTV2DemoCommon::GetTSIMuxesForFrameStore(mDevice, frameStores.at(0), UWord(frameStores.size()));
1258  cscs = ::NTV2MakeChannelList(mConfig.fOutputChannel > NTV2_CHANNEL4 ? NTV2_CHANNEL5 : NTV2_CHANNEL1, isQuadFmt ? 4 : 2);
1259  //cerr << " FrmSt: " << ::NTV2ChannelListToStr(frameStores) << endl << " TSIMx: " << ::NTV2ChannelListToStr(tsiMuxes) << endl
1260  // << " CSCs: " << ::NTV2ChannelListToStr(cscs) << endl << "SDIOut: " << ::NTV2ChannelListToStr(sdiOutputs) << endl;
1261  mDevice.SetSDITransmitEnable(sdiOuts, true); // Do this again, since sdiOuts changed
1262  for (size_t ndx(0); ndx < cscs.size(); ndx++)
1263  { NTV2Channel frmSt (frameStores.at(ndx/2)), tsiMux (tsiMuxes.at(ndx/2)),
1264  sdiOut (sdiOutputs.at(is4KHFR ? ndx : ndx/2)), csc (cscs.at(ndx));
1265  mConnections.insert(NTV2XptConnection(::GetTSIMuxInputXptFromChannel(tsiMux,/*linkB?*/ndx & 1),
1266  ::GetFrameBufferOutputXptFromChannel(frmSt, true/*isRGB*/, ndx & 1/*is425*/)));
1267  mConnections.insert(NTV2XptConnection(::GetCSCInputXptFromChannel(csc),
1268  ::GetTSIMuxOutputXptFromChannel(tsiMux, /*isLinkB*/ndx & 1, /*isRGB*/true)));
1269  mConnections.insert(NTV2XptConnection(::GetSDIOutputInputXpt(sdiOut, /*isDS2*/is4KHFR ? false : ndx & 1),
1270  ::GetCSCOutputXptFromChannel(cscs.at(ndx))));
1271  //*UNCOMMENT TO SHOW ROUTING PROGRESS WHILE DEBUGGING*/mDevice.ApplySignalRoute(mConnections);
1272  }
1273  }
1274  }
1275  else if (!isRGBFBF && isRGBWire)
1276  {
1277  if (!mConfig.fDoTsiRouting) // YUVFrameStore ==> CSC ==> DLOut ==> SDIOut
1278  for (size_t ndx(0); ndx < sdiOutputs.size(); ndx++)
1279  { NTV2Channel frmSt(frameStores.at(ndx)), sdiOut(sdiOutputs.at(ndx));
1280  mConnections.insert(NTV2XptConnection(::GetCSCInputXptFromChannel(frmSt, /*isKeyInput*/false), ::GetFrameBufferOutputXptFromChannel(frmSt, false/*isRGB*/, false/*is425*/)));
1281  mConnections.insert(NTV2XptConnection(::GetDLOutInputXptFromChannel(sdiOut), ::GetCSCOutputXptFromChannel(frmSt, /*isKey*/false, /*isRGB*/true)));
1282  mConnections.insert(NTV2XptConnection(::GetSDIOutputInputXpt(sdiOut, /*isDS2*/false), ::GetDLOutOutputXptFromChannel(sdiOut, /*isDS2*/false)));
1283  mConnections.insert(NTV2XptConnection(::GetSDIOutputInputXpt(sdiOut, /*isDS2*/true), ::GetDLOutOutputXptFromChannel(sdiOut, /*isDS2*/true)));
1284  //*UNCOMMENT TO SHOW ROUTING PROGRESS WHILE DEBUGGING*/mDevice.ApplySignalRoute(mConnections);
1285  // Disable SDI output conversions
1286  mDevice.SetSDIOutLevelAtoLevelBConversion(sdiOut, false);
1287  mDevice.SetSDIOutRGBLevelAConversion(sdiOut, false);
1288  }
1289  else
1290  { // YUVFrameStore ==> 425MUX ==> 2x CSC ==> 2x DLOut ==> 2x SDIOut
1291  sdiOuts = ::NTV2MakeChannelSet(sdiOutput, UWord(2*mActiveFrameStores.size()));
1292  sdiOutputs = ::NTV2MakeChannelList(sdiOuts);
1293  tsiMuxes = CNTV2DemoCommon::GetTSIMuxesForFrameStore(mDevice, frameStores.at(0), UWord(frameStores.size()*2));
1294  mDevice.SetSDITransmitEnable(sdiOuts, true); // Gotta do this again, since sdiOuts changed
1295  for (size_t ndx(0); ndx < sdiOutputs.size(); ndx++)
1296  { NTV2Channel frmSt(frameStores.at(ndx/2)), tsiMux(tsiMuxes.at(ndx/2)), sdiOut(sdiOutputs.at(ndx));
1297  mConnections.insert(NTV2XptConnection(::GetTSIMuxInputXptFromChannel(tsiMux,/*linkB?*/false), ::GetFrameBufferOutputXptFromChannel(frmSt, false/*isRGB*/, false/*is425*/)));
1298  mConnections.insert(NTV2XptConnection(::GetTSIMuxInputXptFromChannel(tsiMux,/*linkB?*/true), ::GetFrameBufferOutputXptFromChannel(frmSt, false/*isRGB*/, true/*is425*/)));
1299  mConnections.insert(NTV2XptConnection(::GetCSCInputXptFromChannel(sdiOut, /*isKeyInput*/false), ::GetTSIMuxOutputXptFromChannel(tsiMux, /*linkB*/(ndx & 1) > 0,/*isRGB*/false)));
1300  mConnections.insert(NTV2XptConnection(::GetDLOutInputXptFromChannel(sdiOut), ::GetCSCOutputXptFromChannel(NTV2Channel(sdiOut),/*isKey*/false,/*isRGB*/true)));
1301  mConnections.insert(NTV2XptConnection(::GetSDIOutputInputXpt(sdiOut, /*isDS2*/false), ::GetDLOutOutputXptFromChannel(sdiOut, /*isDS2*/false)));
1302  mConnections.insert(NTV2XptConnection(::GetSDIOutputInputXpt(sdiOut, /*isDS2*/true), ::GetDLOutOutputXptFromChannel(sdiOut, /*isDS2*/true)));
1303  //*UNCOMMENT TO SHOW ROUTING PROGRESS WHILE DEBUGGING*/mDevice.ApplySignalRoute(mConnections);
1304  }
1305  }
1306  }
1307  else // !isRGBFBF && !isRGBWire
1308  {
1309  if (!mConfig.fDoTsiRouting) // YUVFrameStore ==> SDIOut
1310  for (size_t ndx(0); ndx < sdiOutputs.size(); ndx++)
1311  { NTV2Channel frmSt(frameStores.at(ndx)), sdiOut(sdiOutputs.at(ndx));
1312  mConnections.insert(NTV2XptConnection(::GetSDIOutputInputXpt(sdiOut),
1314  //*UNCOMMENT TO SHOW ROUTING PROGRESS WHILE DEBUGGING*/mDevice.ApplySignalRoute(mConnections);
1315  // Disable SDI output conversions
1316  mDevice.SetSDIOutLevelAtoLevelBConversion(sdiOut, false);
1317  mDevice.SetSDIOutRGBLevelAConversion(sdiOut, false);
1318  }
1319  else
1320  { // TSI // YUVFrameStore ==> 425MUX ==> SDIOut (LFR: 2 x DS1&DS2, 4KHFR: 4 x DS1)
1321  sdiOuts = ::NTV2MakeChannelSet(sdiOutput, is4KHFR ? 4 : UWord(mActiveFrameStores.size()));
1322  sdiOutputs = ::NTV2MakeChannelList(sdiOuts);
1323  tsiMuxes = CNTV2DemoCommon::GetTSIMuxesForFrameStore(mDevice, frameStores.at(0), UWord(frameStores.size()));
1324  //cerr << "FrameStores: " << ::NTV2ChannelListToStr(frameStores) << endl << "SDIOutputs: " << ::NTV2ChannelListToStr(sdiOutputs) << endl
1325  // << "TSIMuxers: " << ::NTV2ChannelListToStr(tsiMuxes) << endl;
1326  mDevice.SetSDITransmitEnable(sdiOuts, true); // Do this again, since sdiOuts changed
1327  for (size_t ndx(0); ndx < sdiOutputs.size(); ndx++)
1328  { NTV2Channel frmSt(frameStores.at(is4KHFR ? ndx/2 : ndx)),
1329  tsiMux(tsiMuxes.at(is4KHFR ? ndx/2 : ndx)),
1330  sdiOut(sdiOutputs.at(ndx));
1331  mConnections.insert(NTV2XptConnection(::GetSDIOutputInputXpt(sdiOut, /*isDS2*/false),
1332  ::GetTSIMuxOutputXptFromChannel(tsiMux, /*linkB?*/is4KHFR && (ndx & 1), /*RGB?*/false)));
1333  if (!is4KHFR)
1334  mConnections.insert(NTV2XptConnection(::GetSDIOutputInputXpt(sdiOut, /*isDS2*/true),
1335  ::GetTSIMuxOutputXptFromChannel(tsiMux, /*linkB?*/true, /*RGB?*/false)));
1336  mConnections.insert(NTV2XptConnection(::GetTSIMuxInputXptFromChannel(tsiMux,/*linkB?*/is4KHFR && (ndx & 1)),
1337  ::GetFrameBufferOutputXptFromChannel(frmSt, /*RGB?*/false, /*425?*/is4KHFR && (ndx & 1))));
1338  if (!is4KHFR)
1339  mConnections.insert(NTV2XptConnection(::GetTSIMuxInputXptFromChannel(tsiMux,/*linkB?*/true),
1340  ::GetFrameBufferOutputXptFromChannel(frmSt, /*RGB?*/false, /*425?*/true)));
1341  //*UNCOMMENT TO SHOW ROUTING PROGRESS WHILE DEBUGGING*/mDevice.ApplySignalRoute(mConnections);
1342  }
1343  }
1344  }
1345  return mDevice.ApplySignalRoute(mConnections, /*replaceExistingRouting?*/!mConfig.fDoMultiFormat) ? AJA_STATUS_SUCCESS : AJA_STATUS_UNSUPPORTED;
1346 
1347 } // RouteOutputSignal
1348 
1349 
1351 {
1352  // Start the threads...
1355  return AJA_STATUS_SUCCESS;
1356 
1357 } // Run
1358 
1359 
1361 // Caption generator thread
1363 
1365 { public:
1368  uint32_t fSpare;
1369  explicit CapGenStartInfo (NTV2CCPlayer * pPlayer, const NTV2Line21Channel inCapChan)
1370  : fpPlayer(pPlayer), fCapChannel(inCapChan)
1371  {}
1372 };
1373 
1374 
1376 {
1377  // Create and start the caption generator threads, one per caption channel...
1378  for (CaptionChanGenMapCIter it(mConfig.fCapChanGenConfigs.begin()); it != mConfig.fCapChanGenConfigs.end(); ++it)
1379  {
1380  const CCGenConfig & genConfig (it->second);
1381  AJAThread & genThread (mGeneratorThreads.at(size_t(genConfig.fCaptionChannel)));
1382  // The generator thread needs to know the NTV2CCPlayer instance, and the caption channel:
1384  reinterpret_cast<void*>(new CapGenStartInfo(this, genConfig.fCaptionChannel)));
1385  genThread.Start();
1386  }
1387 } // StartCaptionGeneratorThreads
1388 
1389 
1390 void NTV2CCPlayer::CaptionGeneratorThreadStatic (AJAThread * pThread, void * pContext) // STATIC
1391 { (void) pThread;
1392  // Extract all the startup info I need...
1393  const CapGenStartInfo * pStartInfo (reinterpret_cast<CapGenStartInfo*>(pContext));
1394  NTV2_ASSERT(pStartInfo);
1395  NTV2CCPlayer * pApp (pStartInfo->fpPlayer);
1396  NTV2_ASSERT(pApp);
1397  const NTV2Line21Channel captionChannel (pStartInfo->fCapChannel);
1398  NTV2_ASSERT(IsValidLine21Channel(captionChannel));
1399  delete pStartInfo; // Done with it, free it
1400 
1401  // Start generating captions for the given caption channel...
1402  pApp->GenerateCaptions(captionChannel);
1403 
1404 } // CaptionGeneratorThreadStatic
1405 
1406 
1408 {
1409  CaptionChanGenMapCIter iter(mConfig.fCapChanGenConfigs.find(inCCChannel));
1410  NTV2_ASSERT(iter != mConfig.fCapChanGenConfigs.end());
1411 
1412  const CCGenConfig & ccGenConfig (iter->second);
1413  const NTV2Line21Mode captionMode (ccGenConfig.fCaptionMode); // My caption mode (paint-on, pop-on, roll-up, etc.)
1414  const double charsPerMinute (ccGenConfig.fCharsPerMinute); // Desired caption rate (in characters per minute)
1415  const bool newlinesMakeNewRows (ccGenConfig.fNewLinesAreNewRows); // Newline characters cause row breaks?
1416  const AtEndAction endAction (ccGenConfig.fEndAction); // What to do after last file is done playing
1417  NTV2StringList filesToPlay (ccGenConfig.fFilesToPlay); // List of text files to play
1418  UWord linesWanted (3); // Desired number of lines to Enqueue in one shot (min 1, max 4)
1419  bool quitThisGenerator (false); // Set true to exit this function/thread
1420  const UWord paintPopTopRow (9); // PaintOn/PopOn only: top display row
1421  const UWord paintPopMaxNumRows (15 - paintPopTopRow + 1); // PaintOn/PopOn only: number of rows to fill to bottom
1422  UWord lineTally (0); // PaintOn/PopOn only: used to calculate display row
1423  const string ccChannelStr (::NTV2Line21ChannelToStr(inCCChannel));
1424 
1426  static const NTV2Line21Attrs sBluCynItal (NTV2_CC608_Blue, NTV2_CC608_Cyan, NTV2_CC608_Opaque, /*italic*/true);
1427  static const NTV2Line21Attrs sRedBlkFlas (NTV2_CC608_Red, NTV2_CC608_Black, NTV2_CC608_Opaque, /*italic*/false, /*UL*/false, /*flash*/true);
1428  static const NTV2Line21Attrs sBluGrnSemiUL (NTV2_CC608_Blue, NTV2_CC608_Green, NTV2_CC608_SemiTransparent, /*italic*/false, /*UL*/true);
1429  static const NTV2Line21Attrs sMgnCynItal (NTV2_CC608_Magenta,NTV2_CC608_Cyan, NTV2_CC608_SemiTransparent, /*italic*/true);
1430  static const NTV2Line21Attrs sAttrs[] = { NTV2Line21Attrs(), sBlkYelSemi, sBluCynItal, sRedBlkFlas, sBluGrnSemiUL, sMgnCynItal};
1431 
1432  PLNOTE("Started " << ccChannelStr << " generator thread");
1433  if (IsLine21TextChannel(inCCChannel) || !IsLine21RollUpMode(captionMode))
1434  linesWanted = 1;
1435  while (!mCaptionGeneratorQuit)
1436  {
1437  CaptionSourceList captionSources(::GetCaptionSources(filesToPlay, charsPerMinute));
1438  while (!mCaptionGeneratorQuit && !captionSources.empty())
1439  {
1440  CaptionSourcePtr captionSource(captionSources.front());
1441  captionSources.pop_front();
1442 
1443  // Set CaptionSource to Text Mode if caption channel is TX1/TX2/TX3/TX4...
1444  captionSource->SetTextMode(IsLine21TextChannel(inCCChannel));
1445  captionSource->SetCaptionChannel(inCCChannel);
1446 
1447  while (!mCaptionGeneratorQuit && !captionSource->IsFinished())
1448  {
1449  // Enqueue another message only if the encoder has less than 200 messages queued up...
1450  // (This prevents runaway memory consumption)
1451  if (m608Encoder->GetQueuedMessageCount() < 200)
1452  {
1453  if (captionSource->IsPlainTextSource())
1454  {
1455  string str (captionSource->GetNextCaptionRow(newlinesMakeNewRows));
1456 
1457  if (IsLine21CaptionChannel(inCCChannel) && !IsLine21RollUpMode(captionMode) && linesWanted > 1)
1458  for (UWord lines(linesWanted - 1); lines; lines--)
1459  str += "\n" + captionSource->GetNextCaptionRow();
1460 
1461  if (!mConfig.fEmitStats && !str.empty())
1462  cout << str << endl; // Echo caption lines (if not emitting stats)
1463  PLDBG(ccChannelStr << " caption line " << DEC(lineTally+1) << ": '" << str << "'");
1464 
1465  const NTV2Line21Attrs & attrs (sAttrs[lineTally % 6]); // Cycle thru different display attributes
1466 
1467  // For now, only the 608 encoder generates caption data.
1468  // Someday we may generate captions using 708-specific features (e.g., windowing, etc.).
1469 
1470  // Convert the UTF-8 string into a string containing CEA-608 byte codes expected
1471  // by Enqueue*Message functions (except EnqueueTextMessage, which accepts UTF-8)...
1472  if (!IsLine21TextChannel(inCCChannel))
1473  str = CUtf8Helpers::Utf8ToCEA608String(str, inCCChannel);
1474  switch (captionMode)
1475  {
1477  m608Encoder->EnqueuePopOnMessage (str, inCCChannel,
1478  /*row*/lineTally % paintPopMaxNumRows + paintPopTopRow,
1479  /*col*/1,
1480  /*attrs*/attrs);
1481  break;
1485  m608Encoder->EnqueueRollUpMessage (str, captionMode, inCCChannel,
1486  /*row*/0, /*col*/0,
1487  /*attrs*/attrs);
1488  break;
1490  m608Encoder->EnqueuePaintOnMessage (str,
1491  /*eraseFirst*/lineTally % paintPopMaxNumRows == 0,
1492  /*chan*/inCCChannel,
1493  /*row*/lineTally % paintPopMaxNumRows + paintPopTopRow,
1494  /*col*/1,
1495  /*attrs*/attrs);
1496  break;
1497  default:
1498  NTV2_ASSERT (IsLine21TextChannel(inCCChannel));
1499  m608Encoder->EnqueueTextMessage (str, lineTally == 0, inCCChannel);
1500  break;
1501  } // switch on caption mode
1502  lineTally++;
1503  } // if plaintext caption source
1504  else
1505  { // This caption source returns raw CC data byte pairs...
1506  SCCSource & sccSource(AsSCCSource(*captionSource));
1507  sccSource.EnqueueCCDataToFrame(m608Encoder, mACStatus.GetProcessedFrameCount());
1508  }
1509  } // if encoder has < 200 messages queued
1510  else
1511  AJATime::Sleep(1000);
1512  } // loop til captionSource is finished (or mCaptionGeneratorQuit)
1513  captionSource->SetCaptionChannel(NTV2_CC608_ChannelInvalid);
1514  } // for each captionSource
1515 
1516  switch (endAction)
1517  {
1518  case AtEndAction_Quit: PLINFO(ccChannelStr << " generator signaling 'main' to terminate");
1519  filesToPlay.clear(); // Clear to-do list if we loop again
1520  ::SignalHandler(SIG_AJA_STOP); // Signal 'main' to terminate
1521  quitThisGenerator = true; // Instantly terminates me
1522  break;
1523 
1524  case AtEndAction_Repeat: PLINFO(ccChannelStr << " generator repeating");
1525  break;
1526 
1527  case AtEndAction_Idle: PLINFO(ccChannelStr << " generator entering idle mode");
1528  filesToPlay.clear(); // Clear to-do list if we loop again
1529  quitThisGenerator = true; // Instantly terminates me
1530  break;
1531 
1532  default: NTV2_ASSERT (false && "bad end action");
1533  break;
1534  }
1535  if (quitThisGenerator)
1536  break;
1537  } // loop til mCaptionGeneratorQuit
1538 
1539  // Let's be nice, and inject an EDM (Erase Displayed Memory) control message.
1540  // This will prevent frozen, on-screen captions from remaining in/on downstream decoders/monitors...
1541  m608Encoder->Erase (inCCChannel);
1542  PLNOTE(ccChannelStr << " generator thread exit");
1543 
1544 } // GenerateCaptions
1545 
1546 
1548 // Playout thread
1550 
1551 
1553 {
1554  // Create and start the playout thread...
1555  mPlayThread.Attach(PlayThreadStatic, this);
1556  mPlayThread.SetPriority(AJA_ThreadPriority_High);
1557  mPlayThread.Start();
1558 } // StartPlayoutThread
1559 
1560 
1561 // The playout thread function
1562 void NTV2CCPlayer::PlayThreadStatic (AJAThread * pThread, void * pContext) // static
1563 { (void) pThread;
1564  // Grab the NTV2CCPlayer instance pointer from the pContext parameter,
1565  // then call its PlayoutFrames method...
1566  NTV2CCPlayer * pApp (reinterpret_cast<NTV2CCPlayer*>(pContext));
1567  pApp->PlayoutFrames ();
1568 } // PlayThreadStatic
1569 
1570 
1572 {
1575  static const uint32_t AUDIOBYTES_MAX_48K (201 * 1024); // Max audio bytes per frame (16 chls x 4 bytes x 67 msec/fr x 48000 Hz)
1576  static const double gAmplitudes [16] = { 0.10, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40,
1577  0.45, 0.50, 0.55, 0.60, 0.65, 0.70, 0.75,
1578  0.80, 0.85};
1579  static const double gFrequencies [16] = { 150.00000000, 200.00000000, 266.66666667, 355.55555556, 474.07407407, 632.09876543,
1580  842.79835391, 1123.73113855, 1498.30818473, 1997.74424630, 2663.65899507, 3551.54532676,
1581  4735.39376902, 6313.85835869, 8418.47781159, 11224.63708211};
1582  // 1080i 720p 525i 625i 1080p 2KFilm 2K1080p 2K1080i UHD 4K UHDHFR 4KHFR
1583  static const uint16_t gF2LineNums608[] = { 573, 0, 273, 323, 0, 1000, 0, 573, 0, 0, 0 }; // Line 10 equivs for F2
1584  static const uint16_t kF1PktLineNumCEA708(9), kF1PktLineNumCEA608(10);
1585  const NTV2SmpteLineNumber smpteLineNumInfo (::GetSmpteLineNumber(mVideoStandard));
1586  const uint16_t kF2PktLineNumCEA608 (gF2LineNums608[mVideoStandard]);
1587  const uint32_t F2StartLine (smpteLineNumInfo.GetLastLine(smpteLineNumInfo.firstFieldTop ? NTV2_FIELD0 : NTV2_FIELD1) + 1); // F2 VBI starts here
1588  static const AJAAncDataLoc kCEA708LocF1 (AJAAncDataLink_A, AJAAncDataChannel_Y, AJAAncDataSpace_VANC, kF1PktLineNumCEA708, AJAAncDataHorizOffset_AnyVanc);
1589  const NTV2FormatDescriptor formatDesc (mConfig.fVideoFormat, mConfig.fPixelFormat, mConfig.fVancMode);
1590  const ULWord bytesPerRow (formatDesc.GetBytesPerRow());
1591  const bool isProgressive (::IsProgressivePicture(mConfig.fVideoFormat));
1592  const bool isInterlaced (!isProgressive);
1593  CNTV2Line21Captioner Line21Encoder; // Used to encode "analog" (line 21) waveform
1594  CaptionData captionData; // Current frame's 608 caption byte pairs (both fields)
1595  ULWord acOptionFlags (0);
1596  ULWord currentSample (0);
1598  ULWord numAudioChannels (0);
1599  Bouncer<UWord> colBouncer (32 - 11 /*upperLimit*/, 0 /*lowerLimit*/, 0 /*startAt*/);
1600  NTV2Buffer audioBuffer;
1601  AUTOCIRCULATE_TRANSFER xferInfo;
1602 
1603  if (NTV2_IS_VANCMODE_OFF(mConfig.fVancMode))
1604  {
1605  xferInfo.acANCBuffer.Allocate(2048);
1606  if (isInterlaced)
1607  xferInfo.acANCField2Buffer.Allocate(2048);
1608  }
1609 
1610  if (!mConfig.fSuppressAudio)
1611  {
1612  // Audio setup...
1613  audioSystem = (mDevice.features().GetNumAudioSystems() > 1) ? ::NTV2ChannelToAudioSystem(mConfig.fOutputChannel) : NTV2_AUDIOSYSTEM_1;
1614  numAudioChannels = mDevice.features().GetMaxAudioChannels();
1615  if (NTV2_IS_4K_4096_VIDEO_FORMAT(mConfig.fVideoFormat) && numAudioChannels > 8)
1616  numAudioChannels = 8; // 2K/4096-pixel lines have narrower HANC space & can't handle 16 channels
1617  mDevice.SetNumberAudioChannels (numAudioChannels, audioSystem); // Config audio: # channels
1618  mDevice.SetAudioRate (NTV2_AUDIO_48K, audioSystem); // Config audio: 48kHz sample rate
1619  mDevice.SetAudioBufferSize (NTV2_AUDIO_BUFFER_BIG, audioSystem); // Config audio: Use 4MB output buffer
1620  mDevice.SetSDIOutputAudioSystem (mConfig.fOutputChannel, audioSystem); // Set output DS1 audio embedders to use designated audio system
1621  mDevice.SetSDIOutputDS2AudioSystem (mConfig.fOutputChannel, audioSystem); // Set output DS2 audio embedders to use designated audio system
1622  mDevice.SetAudioLoopBack (NTV2_AUDIO_LOOPBACK_OFF, audioSystem); // Config audio: Disable loopback (not E-E)
1623  audioBuffer.Allocate(AUDIOBYTES_MAX_48K); // Allocate audio buffer (large enough for one frame's audio)
1624  if (!mConfig.fDoMultiFormat)
1625  {
1626  for (UWord chan (0); chan < mDevice.features().GetNumVideoOutputs(); chan++)
1627  {
1628  mDevice.SetSDIOutputAudioSystem (NTV2Channel (chan), audioSystem);
1629  mDevice.SetSDIOutputDS2AudioSystem (NTV2Channel (chan), audioSystem);
1630  }
1631  if (mDevice.features().GetNumHDMIAudioOutputChannels() == 8)
1632  {
1634  mDevice.SetHDMIOutAudioSource8Channel (NTV2_AudioChannel1_8, audioSystem);
1635  }
1636  } // if not multiformat
1637  } // if audio not suppressed
1638 
1639  // Set up the transfer buffers...
1640  xferInfo.SetVideoBuffer(reinterpret_cast<ULWord *>(mVideoBuffer.GetHostPointer()), mVideoBuffer.GetByteCount());
1641  if (mConfig.fSuppressTimecode)
1642  xferInfo.acOutputTimeCodes.Set (AJA_NULL, 0);
1643  PLNOTE("Playout thread started: 608F1PktLine=" << DEC(kF1PktLineNumCEA608) << " 608F2PktLine=" << DEC(kF2PktLineNumCEA608)
1644  << " 708F1PktLine=" << DEC(kF1PktLineNumCEA708) << " F2StartLine=" << DEC(F2StartLine));
1645 
1647  mDevice.GetFrameRate(frameRate, mConfig.fOutputChannel);
1649 
1650  // Set up playout AutoCirculate and start it...
1651  if (NTV2_IS_VANCMODE_OFF(mConfig.fVancMode))
1652  acOptionFlags |= AUTOCIRCULATE_WITH_ANC;
1653  if (!mConfig.fSuppressTimecode)
1654  acOptionFlags |= AUTOCIRCULATE_WITH_RP188;
1655  if (!mConfig.fSuppressTimecode && !mConfig.fDoMultiFormat && mDevice.features().GetNumLTCOutputs())
1656  acOptionFlags |= AUTOCIRCULATE_WITH_LTC; // Emit analog LTC if we "own" the device
1657  mDevice.AutoCirculateStop (mConfig.fOutputChannel); // Maybe some other app left this A/C channel running
1658  if (NTV2_IS_SD_VIDEO_FORMAT(mConfig.fVideoFormat) && mConfig.fSuppressLine21 && mConfig.fSuppress608)
1659  cerr << "## WARNING: SD video with '--noline21' option and '--no608' option won't produce captions" << endl;
1660  if (mDevice.AutoCirculateInitForOutput (mConfig.fOutputChannel,
1661  mConfig.fFrames.count(), // numFrames (zero if specifying range)
1662  audioSystem,
1663  acOptionFlags,
1664  1, // numChannels to gang
1665  mConfig.fFrames.firstFrame(), mConfig.fFrames.lastFrame()))
1666  mDevice.AutoCirculateStart (mConfig.fOutputChannel);
1667  else
1668  {cerr << "## ERROR: AutoCirculateInitForOutput failed" << endl; mPlayerQuit = true;}
1669 
1670  // Repeat until time to quit...
1671  while (!mPlayerQuit)
1672  { // Check AutoCirculate status...
1673  mDevice.AutoCirculateGetStatus (mConfig.fOutputChannel, mACStatus);
1674  if (!mACStatus.CanAcceptMoreOutputFrames())
1675  { // Out of room on the device for new frame...
1676  mDevice.WaitForOutputVerticalInterrupt (mConfig.fOutputChannel); // Wait for next VBI
1677  continue; // Try again
1678  }
1679  if (NTV2_IS_VANCMODE_OFF(mConfig.fVancMode))
1680  {xferInfo.acANCBuffer.Fill(ULWord(0)); xferInfo.acANCField2Buffer.Fill(ULWord(0));} // Clear Anc buffers before filling
1681 
1682  AJAAncillaryList packetList; // List of packets to be transmitted
1683  m608Encoder->GetNextCaptionData(captionData); // Pop queued captions from 608 encoder waiting to be transmitted
1684  if (!mConfig.fSuppress608)
1685  {
1687 
1688  pkt608F1.SetLocationLineNumber (kF1PktLineNumCEA608);
1689  pkt608F1.SetCEA608Bytes (captionData.f1_char1, captionData.f1_char2);
1690  pkt608F1.GeneratePayloadData();
1691  packetList.AddAncillaryData(pkt608F1);
1692  if (!NTV2_IS_PROGRESSIVE_STANDARD(mVideoStandard))
1693  { NTV2_ASSERT(kF2PktLineNumCEA608);
1695  pkt608F2.SetLocationLineNumber(kF2PktLineNumCEA608);
1696  pkt608F2.SetCEA608Bytes (captionData.f2_char1, captionData.f2_char2);
1697  pkt608F2.GeneratePayloadData();
1698  packetList.AddAncillaryData(pkt608F2);
1699  }
1700  }
1701 
1703  { // SD Video encodes "analog" waveform into line 21...
1704  if (!mConfig.fSuppressLine21)
1705  { // Overwrite Line21 with encoded CEA608 waveform
1706  ULWord line21RowOffset (0);
1707  UByte * pLine21 (AJA_NULL);
1708  UByte * pEncodedYUV8Line (AJA_NULL);
1709  formatDesc.GetLineOffsetFromSMPTELine (21, line21RowOffset);
1710  pLine21 = reinterpret_cast<UByte*>(formatDesc.GetWriteableRowAddress(mVideoBuffer.GetHostPointer(), line21RowOffset));
1711  if (pLine21)
1712  { // Encode F1 caption bytes into EIA-608-compliant 8-bit YUV waveform...
1713  pEncodedYUV8Line = Line21Encoder.EncodeLine (captionData.f1_char1, captionData.f1_char2);
1714  // Replace F1 line 21 in the frame buffer with the EncodeLine result...
1715  if (mConfig.fPixelFormat == NTV2_FBF_8BIT_YCBCR)
1716  ::memcpy (pLine21, pEncodedYUV8Line, bytesPerRow); // ... just copy the line
1717  else if (mConfig.fPixelFormat == NTV2_FBF_10BIT_YCBCR)
1718  ::ConvertLine_2vuy_to_v210 (pEncodedYUV8Line, reinterpret_cast<ULWord*>(pLine21), 720); // ...with EncodeLine result converted to 10-bit YUV
1719  }
1720  else PLFAIL("GetWriteableRowAddress return NULL for SMPTE line 21, rowOffset=" << xHEX0N(line21RowOffset,8) << " " << formatDesc);
1721 
1722  formatDesc.GetLineOffsetFromSMPTELine (284, line21RowOffset);
1723  pLine21 = reinterpret_cast<UByte*>(formatDesc.GetWriteableRowAddress(mVideoBuffer.GetHostPointer(), line21RowOffset));
1724  if (pLine21)
1725  { // Encode F2 caption bytes into EIA-608-compliant 8-bit YUV waveform...
1726  pEncodedYUV8Line = Line21Encoder.EncodeLine (captionData.f2_char1, captionData.f2_char2);
1727  // Replace F2 line 21 in the frame buffer with the EncodeLine result...
1728  if (mConfig.fPixelFormat == NTV2_FBF_8BIT_YCBCR)
1729  ::memcpy (pLine21, pEncodedYUV8Line, bytesPerRow); // ... just copy the line
1730  else if (mConfig.fPixelFormat == NTV2_FBF_10BIT_YCBCR)
1731  ::ConvertLine_2vuy_to_v210 (pEncodedYUV8Line, reinterpret_cast<ULWord*>(pLine21), 720); // ...with EncodeLine result converted to 10-bit YUV
1732  }
1733  else PLFAIL("GetWriteableRowAddress return NULL for SMPTE line 284, rowOffset=" << xHEX0N(line21RowOffset,8) << " " << formatDesc);
1734  //DEBUG if (captionData.HasData()) mDevice.DMAWriteFrame(33, (ULWord*) mVideoBuffer.GetHostPointer(), mVideoBuffer.GetByteCount());
1735  } // if not suppressing analog line21
1736  } // if SD video
1737  else if (!mConfig.fSuppress708)
1738  { // HD video -- use the 708 encoder to put 608 captions into a single 708 packet:
1739  m708Encoder->Set608CaptionData(captionData); // Set the 708 encoder's 608 caption data (for both F1 and F2)
1740  if (m708Encoder->MakeSMPTE334AncPacket (frameRate, NTV2_CC608_Field1)) // Generate SMPTE-334 Anc data packet
1741  {
1742  AJAAncillaryData_Cea708 pkt708;
1743  pkt708.SetFromSMPTE334 (m708Encoder->GetSMPTE334Data(), uint32_t(m708Encoder->GetSMPTE334Size()), kCEA708LocF1);
1744  packetList.AddAncillaryData(pkt708);
1745  }
1746  } // else HD video
1747 
1748  // PLDBG("Xmit pkts: " << packetList); // DEBUG: Packet list to be transmitted
1749  packetList.SetAllowMultiRTPTransmit(mConfig.fForceRTP & BIT(1));
1750  if (NTV2_IS_VANCMODE_ON(mConfig.fVancMode)) // Write FB VANC lines...
1751  packetList.GetVANCTransmitData (mVideoBuffer, formatDesc);
1752  else if (mConfig.fForceRTP) // Force RTP? Non-IP2110 devices won't understand what's in the Anc buffer...
1753  packetList.GetIPTransmitData(xferInfo.acANCBuffer, xferInfo.acANCField2Buffer, isProgressive, F2StartLine);
1754  else // Else use the Anc inserter firmware:
1755  packetList.GetTransmitData (xferInfo.acANCBuffer, xferInfo.acANCField2Buffer, isProgressive, F2StartLine);
1756 
1757  if (mConfig.fForceRTP && mConfig.fForceRTP & BIT(1) && mDevice.features().CanDo2110())
1758  xferInfo.acTransferStatus.acState = NTV2_AUTOCIRCULATE_INVALID; // Signal MultiPkt RTP to AutoCirculateTransfer/S2110DeviceAncToXferBuffers
1759 
1760  if (!mConfig.fSuppressTimecode)
1761  {
1762  const CRP188 rp188 (mACStatus.GetProcessedFrameCount(), tcFormat);
1763  char tcString[] = {" "};
1764  const UWord colShift (mACStatus.GetProcessedFrameCount() % 10 == 0 ? colBouncer.Next() : colBouncer.Value());
1765  bool tcOK (false);
1766  NTV2_RP188 tc;
1767  rp188.GetRP188Reg (tc);
1768  if (!NTV2_IS_QUAD_FRAME_FORMAT(mConfig.fVideoFormat) && !mConfig.fDoMultiFormat)
1769  // UniFormat and not Quad Frame: i.e. using ALL output spigots:
1770  // AutoCirculateTransfer will automatically set ALL output timecodes to
1771  // the DEFAULT timecode if the DEFAULT timecode is valid...
1772  tcOK = xferInfo.SetOutputTimeCode(tc, NTV2_TCINDEX_DEFAULT);
1773  else
1774  { // MULTI-FORMAT OR QUAD-FRAME:
1775  // Be more selective as to which output spigots get the generated timecode...
1776  NTV2TimeCodes timecodes;
1777  for (int num (0); num < 4; num++)
1778  {
1779  const NTV2Channel chan (NTV2Channel(mConfig.fOutputChannel + num));
1780  timecodes[::NTV2ChannelToTimecodeIndex(chan, /*inEmbeddedLTC*/false)] = tc;
1781  timecodes[::NTV2ChannelToTimecodeIndex(chan, /*inEmbeddedLTC*/true)] = tc;
1782  if (isInterlaced)
1783  timecodes[::NTV2ChannelToTimecodeIndex(chan, /*inEmbeddedLTC*/false, /*inIsF2*/true)] = tc;
1784  if (acOptionFlags & AUTOCIRCULATE_WITH_LTC)
1785  {
1786  timecodes[NTV2_TCINDEX_LTC1] = tc;
1787  if (mDevice.features().GetNumLTCOutputs() > 1)
1788  timecodes[NTV2_TCINDEX_LTC2] = tc;
1789  }
1791  break; // Not Quad Frame: just do the one output
1792  } // for each quad
1793  tcOK = xferInfo.SetOutputTimeCodes(timecodes);
1794  }
1795  ::memcpy (tcString + colShift, rp188.GetRP188CString(), 11);
1796  CNTV2CaptionRenderer::BurnString (tcString, tcOK ? kBlueOnWhite : kRedOnYellow, mVideoBuffer, formatDesc, 3, 1); // R3C1
1797  } // if not suppressing timecode injection
1798 
1799  if (audioBuffer)
1800  xferInfo.SetAudioBuffer (audioBuffer,
1801  ::AddAudioTone (audioBuffer, // audio buffer to fill
1802  currentSample, // sample for continuing the waveform
1803  ::GetAudioSamplesPerFrame(frameRate, NTV2_AUDIO_48K, mACStatus.GetProcessedFrameCount()), // # samples to generate
1804  48000.0, // sample rate [Hz]
1805  gAmplitudes, // per-channel amplitudes
1806  gFrequencies, // per-channel tone frequencies [Hz]
1807  31, // bits per sample
1808  false, // false means "don't byte swap"
1809  numAudioChannels)); // number of audio channels
1810  // Finally ... transfer the frame data to the device...
1811  mDevice.AutoCirculateTransfer (mConfig.fOutputChannel, xferInfo);
1812  } // loop til quit signaled
1813 
1814  // Stop AutoCirculate...
1815  mDevice.AutoCirculateStop (mConfig.fOutputChannel);
1816 
1817  // Flush encoder queues (prevent Quit from hanging)...
1818  while(m608Encoder->GetQueuedByteCount(NTV2_CC608_Field1) || m608Encoder->GetQueuedByteCount(NTV2_CC608_Field2))
1819  {m608Encoder->Flush(NTV2_CC608_Field1); m608Encoder->Flush(NTV2_CC608_Field2);}
1820  PLNOTE("Playout thread exit");
1821 
1822 } // PlayoutFrames
1823 
1824 
1825 void NTV2CCPlayer::GetStatus ( size_t & outMessagesQueued, size_t & outBytesQueued,
1826  size_t & outTotMsgsEnq, size_t & outTotBytesEnq,
1827  size_t & outTotMsgsDeq, size_t & outTotBytesDeq,
1828  size_t & outMaxQueDepth, size_t & outDroppedFrames) const
1829 {
1831  if (m608Encoder)
1832  {
1833  outMessagesQueued = m608Encoder->GetQueuedMessageCount();
1834  outBytesQueued = m608Encoder->GetQueuedByteCount();
1835  outTotMsgsEnq = m608Encoder->GetEnqueueMessageTally();
1836  outTotBytesEnq = m608Encoder->GetEnqueueByteTally();
1837  outTotMsgsDeq = m608Encoder->GetDequeueMessageTally();
1838  outTotBytesDeq = m608Encoder->GetDequeueByteTally();
1839  outMaxQueDepth = m608Encoder->GetHighestQueueDepth();
1840  }
1841  else
1842  outMessagesQueued = outBytesQueued = outTotMsgsEnq = outTotBytesEnq = outTotMsgsDeq = outTotBytesDeq = outMaxQueDepth = 0;
1843  outDroppedFrames = size_t(mACStatus.GetDroppedFrameCount());
1844 
1845 } // GetStatus
CaptionSource::~CaptionSource
virtual ~CaptionSource()
My destructor. If was told at construction time that I was to be responsible for deleting the input s...
Definition: ntv2ccplayer.cpp:311
NTV2CCPlayer
I am an object that can inject text captions into an SDI output of an AJA device in real time....
Definition: ntv2ccplayer.h:125
NTV2TestPatternGen::DrawTestPattern
virtual bool DrawTestPattern(const std::string &inTPName, const NTV2FormatDescriptor &inFormatDesc, NTV2Buffer &inBuffer)
Renders the given test pattern or color into a host raster buffer.
CNTV2Card::SubscribeOutputVerticalEvent
virtual bool SubscribeOutputVerticalEvent(const NTV2Channel inChannel)
Causes me to be notified when an output vertical blanking interrupt is generated for the given output...
Definition: ntv2subscriptions.cpp:25
CNTV2Card::SetVANCMode
virtual bool SetVANCMode(const NTV2VANCMode inVancMode, const NTV2Channel inChannel=NTV2_CHANNEL1)
Sets the VANC mode for the given FrameStore.
Definition: ntv2register.cpp:2640
AJAAncillaryData_Cea608::SetCEA608Bytes
virtual AJAStatus SetCEA608Bytes(const uint8_t inByte1, const uint8_t inByte2)
Set the CEA608 payload bytes.
Definition: ancillarydata_cea608.cpp:81
kAppSignature
static const uint32_t kAppSignature(((((uint32_t)( 'C'))<< 24)|(((uint32_t)( 'C'))<< 16)|(((uint32_t)( 'P'))<< 8)|(((uint32_t)( 'L'))<< 0)))
aja::stoul
unsigned long stoul(const std::string &str, std::size_t *idx, int base)
Definition: common.cpp:143
CaptionSource::GetNextCaptionRow
virtual string GetNextCaptionRow(const bool inBreakLinesOnNewLineChars=(0))
Returns the next "sentence" read from my input stream. I build the "sentence" by reading "words" usin...
Definition: ntv2ccplayer.cpp:465
NTV2_CC608_Blue
@ NTV2_CC608_Blue
Definition: ntv2caption608types.h:157
CNTV2Card::SetMultiFormatMode
virtual bool SetMultiFormatMode(const bool inEnable)
Enables or disables multi-format (per channel) device operation. If enabled, each device channel can ...
Definition: ntv2register.cpp:4379
GetSDIOutputInputXpt
NTV2InputXptID GetSDIOutputInputXpt(const NTV2Channel inSDIOutput, const bool inIsDS2=false)
Definition: ntv2signalrouter.cpp:942
CNTV2CaptionEncoder608::GetDequeueMessageTally
virtual size_t GetDequeueMessageTally(void) const
Returns the total number of messages that have been dequeued from me since I was instantiated.
Definition: ntv2captionencoder608.h:339
NTV2_CC608_SemiTransparent
@ NTV2_CC608_SemiTransparent
Definition: ntv2caption608types.h:216
NTV2FormatDescriptor::GetBytesPerRow
ULWord GetBytesPerRow(const UWord inPlaneIndex0=0) const
Definition: ntv2formatdescriptor.h:140
NTV2_IS_SD_VIDEO_FORMAT
#define NTV2_IS_SD_VIDEO_FORMAT(__f__)
Definition: ntv2enums.h:707
DeviceCapabilities::CanDoVideoFormat
bool CanDoVideoFormat(const NTV2VideoFormat inVF)
Definition: ntv2devicecapabilities.h:251
AJAAncDataLoc
Defines where the ancillary data can be found within a video stream.
Definition: ancillarydata.h:225
NTV2_CC608_Black
@ NTV2_CC608_Black
Definition: ntv2caption608types.h:162
DEVICE_ID_KONAIP_2110
@ DEVICE_ID_KONAIP_2110
See KONA IP.
Definition: ntv2enums.h:70
AJAAncillaryList::SetAllowMultiRTPTransmit
virtual void SetAllowMultiRTPTransmit(const bool inAllow)
Determines if multiple RTP packets will be encoded for playout (via GetIPTransmitData)....
Definition: ancillarylist.h:482
NTV2_AUDIO_LOOPBACK_OFF
@ NTV2_AUDIO_LOOPBACK_OFF
Embeds silence (zeroes) into the data stream.
Definition: ntv2enums.h:1975
NTV2FormatDescriptor::GetVideoWriteSize
ULWord GetVideoWriteSize(ULWord inPageSize=4096UL) const
Definition: ntv2formatdescriptor.cpp:862
NTV2CCPlayer::DeviceAncExtractorIsAvailable
virtual bool DeviceAncExtractorIsAvailable(void)
Definition: ntv2ccplayer.cpp:930
CNTV2CaptionEncoder608::GetNextCaptionData
virtual bool GetNextCaptionData(CaptionData &outCaptionData)
This high-level method is used to dequeue caption data for an entire frame.
CaptionSourceListConstIter
CaptionSourceList::const_iterator CaptionSourceListConstIter
Definition: ntv2ccplayer.cpp:274
NTV2_REFERENCE_SFP1_PTP
@ NTV2_REFERENCE_SFP1_PTP
Specifies the PTP source on SFP 1.
Definition: ntv2enums.h:1413
NTV2_FOURCC
#define NTV2_FOURCC(_a_, _b_, _c_, _d_)
Definition: ntv2publicinterface.h:5444
AJA_ThreadPriority_High
@ AJA_ThreadPriority_High
Definition: thread.h:44
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:536
NTV2ACFrameRange::firstFrame
UWord firstFrame(void) const
Definition: ntv2utils.h:975
CNTV2Card::SetVideoFormat
virtual bool SetVideoFormat(const NTV2VideoFormat inVideoFormat, const bool inIsAJARetail=(!(0)), const bool inKeepVancSettings=(0), const NTV2Channel inChannel=NTV2_CHANNEL1)
Configures the AJA device to handle a specific video format.
Definition: ntv2register.cpp:204
CaptionSourcePtr
AJARefPtr< CaptionSource > CaptionSourcePtr
Definition: ntv2ccplayer.cpp:266
NTV2CCPlayer::SetUpOutputVideo
virtual AJAStatus SetUpOutputVideo(void)
Sets up everything I need to play video.
Definition: ntv2ccplayer.cpp:1050
NTV2CCPlayer::PlayoutFrames
virtual void PlayoutFrames(void)
Repeatedly plays frames (until time to quit).
Definition: ntv2ccplayer.cpp:1571
CNTV2Card::Set4kSquaresEnable
virtual bool Set4kSquaresEnable(const bool inIsEnabled, const NTV2Channel inChannel)
Enables or disables SMPTE 425 "2K quadrants" mode for the given FrameStore bank on the device....
Definition: ntv2register.cpp:1238
ntv2transcode.h
Declares a number of pixel format transcoder functions.
CNTV2CaptionEncoder608::GetEnqueueMessageTally
virtual size_t GetEnqueueMessageTally(void) const
Returns the total number of messages that have been enqueued onto me since I was instantiated.
Definition: ntv2captionencoder608.h:334
CNTV2CaptionEncoder608::EnqueuePaintOnMessage
virtual bool EnqueuePaintOnMessage(const std::string &inMessageStr, const bool inEraseFirst=false, const NTV2Line21Channel inChannel=NTV2_CC608_CC1, const UWord inRowNumber=0, const UWord inColumnNumber=0, const NTV2Line21Attrs &inDisplayAttribs=NTV2Line21Attrs())
Enqueues the given message for eventual "paint-on" display.
CaptionData::f2_char1
UByte f2_char1
Caption Byte 1 of Field 2.
Definition: ntv2caption608types.h:662
ntv2devicefeatures.h
Declares device capability functions.
NTV2_AUDIO_BUFFER_BIG
@ NTV2_AUDIO_BUFFER_BIG
Definition: ntv2enums.h:1864
debugshare.h
Declares the constants used for sharing debug messages. These structures are used to gather debug mes...
CaptionChanGenMapCIter
CaptionChanGenMap::const_iterator CaptionChanGenMapCIter
Definition: ntv2ccplayer.h:73
NTV2FormatDescriptor
Describes a video frame for a given video standard or format and pixel format, including the total nu...
Definition: ntv2formatdescriptor.h:41
aja::strip
std::string & strip(std::string &str, const std::string &ws)
Definition: common.cpp:461
types.h
Declares common types used in the ajabase library.
AUTOCIRCULATE_TRANSFER::SetAudioBuffer
bool SetAudioBuffer(ULWord *pInAudioBuffer, const ULWord inAudioByteCount)
Sets my audio buffer for use in a subsequent call to CNTV2Card::AutoCirculateTransfer.
Definition: ntv2publicinterface.cpp:2716
Is8BitFrameBufferFormat
bool Is8BitFrameBufferFormat(const NTV2FrameBufferFormat fbFormat)
Definition: ntv2utils.cpp:5484
CRP188::GetRP188Reg
bool GetRP188Reg(RP188_STRUCT &outRP188) const
Definition: ntv2rp188.cpp:1241
CNTV2DemoCommon::GetTSIMuxesForFrameStore
static NTV2ChannelList GetTSIMuxesForFrameStore(CNTV2Card &inDevice, const NTV2Channel in1stFrameStore, const UWord inCount)
Definition: ntv2democommon.cpp:1182
NTV2Channel
NTV2Channel
These enum values are mostly used to identify a specific widget_framestore. They're also commonly use...
Definition: ntv2enums.h:1305
NTV2Buffer
A generic user-space buffer object that has an address and a length. Used most often to share an arbi...
Definition: ntv2publicinterface.h:5993
CCGenConfig::fNewLinesAreNewRows
bool fNewLinesAreNewRows
If true, newlines break caption rows; otherwise are treated as whitespace.
Definition: ntv2ccplayer.h:50
NTV2SmpteLineNumber::GetLastLine
ULWord GetLastLine(const NTV2FieldID inRasterFieldID=NTV2_FIELD0) const
Definition: ntv2formatdescriptor.cpp:1296
AJA_STATUS_SUCCESS
@ AJA_STATUS_SUCCESS
Definition: types.h:381
NTV2CCPlayer::StartCaptionGeneratorThreads
virtual void StartCaptionGeneratorThreads(void)
Starts my caption generator threads.
Definition: ntv2ccplayer.cpp:1375
AJARefPtr
I am a reference-counted pointer template class. I am intended to be a proxy for an underlying object...
Definition: ajarefptr.h:89
CCPlayerConfig::fForceRTP
uint16_t fForceRTP
BIT(0):0=normal,1=forceRTP BIT(1):0=uniPkt,1=multiPkt BIT(2):0=normal,1=patchDeviceID.
Definition: ntv2ccplayer.h:88
aja::join
std::string join(const std::vector< std::string > &parts, const std::string &delim)
Definition: common.cpp:468
aja::split
void split(const std::string &str, const char delim, std::vector< std::string > &elems)
Definition: common.cpp:350
AtEndAction_Idle
@ AtEndAction_Idle
Repeat the file list (must Ctrl-C to terminate)
Definition: ntv2ccplayer.h:31
NTV2Buffer::GetByteCount
ULWord GetByteCount(void) const
Definition: ntv2publicinterface.h:6066
NTV2_STANDARD_INVALID
@ NTV2_STANDARD_INVALID
Definition: ntv2enums.h:173
Bouncer::Value
T Value(void) const
Definition: ntv2democommon.h:213
NTV2_ASSERT
#define NTV2_ASSERT(_expr_)
Definition: ajatypes.h:506
IsLine21RollUpMode
#define IsLine21RollUpMode(_mode_)
Definition: ntv2caption608types.h:139
GetNTV2FrameRateFromVideoFormat
NTV2FrameRate GetNTV2FrameRateFromVideoFormat(const NTV2VideoFormat inVideoFormat)
Definition: ntv2utils.cpp:3530
SCCSource
Definition: ntv2ccplayer.cpp:630
AtEndAction
enum _AtEndAction_ AtEndAction
These are the actions that can be taken after the last file is "played".
CNTV2CaptionEncoder608::Create
static bool Create(CNTV2CaptionEncoder608Ptr &outEncoder)
Creates a new CNTV2CaptionEncoder608 instance.
CCPlayerConfig
Configures an NTV2CCPlayer instance.
Definition: ntv2ccplayer.h:80
CCGenConfig::fCaptionMode
NTV2Line21Mode fCaptionMode
The CEA-608 caption mode to use.
Definition: ntv2ccplayer.h:48
AJAThread::Attach
virtual AJAStatus Attach(AJAThreadFunction *pThreadFunction, void *pUserContext)
Definition: thread.cpp:169
NTV2_CC608_CapModePaintOn
@ NTV2_CC608_CapModePaintOn
Paint-on caption mode.
Definition: ntv2caption608types.h:131
NTV2_CC608_Cyan
@ NTV2_CC608_Cyan
Definition: ntv2caption608types.h:158
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:1581
NTV2_AUDIO_48K
@ NTV2_AUDIO_48K
Definition: ntv2enums.h:1875
NTV2_CC608_Red
@ NTV2_CC608_Red
Definition: ntv2caption608types.h:159
systemtime.h
Declares the AJATime class.
gBuiltInCaptions
static const string gBuiltInCaptions("IN CONGRESS, July 4, 1776.\n" "The unanimous Declaration of the thirteen united States of America.\n" "When in the Course of human events, it becomes necessary for one people to dissolve the political bands which have connected them with another, " "and to assume among the powers of the earth, the separate and equal station to which the Laws of Nature and of Nature's God entitle them, a decent " "respect to the opinions of mankind requires that they should declare the causes which impel them to the separation.\n" "We hold these truths to be self-evident, that all men are created equal, that they are endowed by their Creator with certain unalienable Rights, " "that among these are Life, Liberty and the pursuit of Happiness. That to secure these rights, Governments are instituted among Men, deriving their " "just powers from the consent of the governed, That whenever any Form of Government becomes destructive of these ends, it is the Right of the People to alter or to abolish it, " "and to institute new Government, laying its foundation on such principles and organizing its powers in such form, as to them shall seem most likely to effect their Safety and " "Happiness. Prudence, indeed, will dictate that Governments long established should not be changed for light and transient causes; and accordingly all experience hath shewn, " "that mankind are more disposed to suffer, while evils are sufferable, than to right themselves by abolishing the forms to which they are accustomed. " "But when a long train of abuses and usurpations, pursuing invariably the same Object evinces a design to reduce them under absolute Despotism, it is their right, " "it is their duty, to throw off such Government, and to provide new Guards for their future security. Such has been the patient sufferance of these Colonies; and such is now " "the necessity which constrains them to alter their former Systems of Government. The history of the present King of Great Britain is a history of repeated injuries and " "usurpations, all having in direct object the establishment of an absolute Tyranny over these States. To prove this, let Facts be submitted to a candid world.\n" "He has refused his Assent to Laws, the most wholesome and necessary for the public good.\n" "He has forbidden his Governors to pass Laws of immediate and pressing importance, unless suspended in their operation till his Assent should be obtained; " "and when so suspended, he has utterly neglected to attend to them.\n" "He has refused to pass other Laws for the accommodation of large districts of people, unless those people would relinquish the right of Representation in the Legislature, " "a right inestimable to them and formidable to tyrants only.\n" "He has called together legislative bodies at places unusual, uncomfortable, and distant from the depository of their public Records, for the sole purpose of fatiguing them " "into compliance with his measures. \n" "He has dissolved Representative Houses repeatedly, for opposing with manly firmness his invasions on the rights of the people.\n" "He has refused for a long time, after such dissolutions, to cause others to be elected; whereby the Legislative powers, incapable of Annihilation, have returned to the People " "at large for their exercise; the State remaining in the mean time exposed to all the dangers of invasion from without, and convulsions within.\n" "He has endeavoured to prevent the population of these States; for that purpose obstructing the Laws for Naturalization of Foreigners; refusing to pass others to encourage " "their migrations hither, and raising the conditions of new Appropriations of Lands.\n" "He has obstructed the Administration of Justice, by refusing his Assent to Laws for establishing Judiciary powers.\n" "He has made Judges dependent on his Will alone, for the tenure of their offices, and the amount and payment of their salaries.\n" "He has erected a multitude of New Offices, and sent hither swarms of Officers to harrass our people, and eat out their substance.\n" "He has kept among us, in times of peace, Standing Armies without the Consent of our legislatures.\n" "He has affected to render the Military independent of and superior to the Civil power.\n" "He has combined with others to subject us to a jurisdiction foreign to our constitution, and unacknowledged by our laws; " "giving his Assent to their Acts of pretended Legislation:\n" "For Quartering large bodies of armed troops among us:\n" "For protecting them, by a mock Trial, from punishment for any Murders which they should commit on the Inhabitants of these States:\n" "For cutting off our Trade with all parts of the world:\n" "For imposing Taxes on us without our Consent:\n" "For depriving us in many cases, of the benefits of Trial by Jury:\n" "For transporting us beyond Seas to be tried for pretended offences.\n" "For abolishing the free System of English Laws in a neighbouring Province, establishing therein an Arbitrary government, and enlarging its Boundaries so as to render it at " "once an example and fit instrument for introducing the same absolute rule into these Colonies:\n" "For taking away our Charters, abolishing our most valuable Laws, and altering fundamentally the Forms of our Governments:\n" "For suspending our own Legislatures, and declaring themselves invested with power to legislate for us in all cases whatsoever.\n" "He has abdicated Government here, by declaring us out of his Protection and waging War against us.\n" "He has plundered our seas, ravaged our Coasts, burnt our towns, and destroyed the lives of our people.\n" "He is at this time transporting large Armies of foreign Mercenaries to compleat the works of death, desolation and tyranny, already begun with circumstances of Cruelty & " "perfidy scarcely paralleled in the most barbarous ages, and totally unworthy the Head of a civilized nation.\n" "He has constrained our fellow Citizens taken Captive on the high Seas to bear Arms against their Country, to become the executioners of their friends and Brethren, " "or to fall themselves by their Hands.\n" "He has excited domestic insurrections amongst us, and has endeavoured to bring on the inhabitants of our frontiers, the merciless Indian Savages, whose known rule of warfare, " "is an undistinguished destruction of all ages, sexes and conditions.\n" "In every stage of these Oppressions We have Petitioned for Redress in the most humble terms: Our repeated Petitions have been answered only by repeated injury. " "A Prince whose character is thus marked by every act which may define a Tyrant, is unfit to be the ruler of a free people.\n" "Nor have We been wanting in attentions to our Brittish brethren. We have warned them from time to time of attempts by their legislature to extend an unwarrantable " "jurisdiction over us. We have reminded them of the circumstances of our emigration and settlement here. We have appealed to their native justice and magnanimity, " "and we have conjured them by the ties of our common kindred to disavow these usurpations, which, would inevitably interrupt our connections and correspondence. " "They too have been deaf to the voice of justice and of consanguinity. We must, therefore, acquiesce in the necessity, which denounces our Separation, and hold them, " "as we hold the rest of mankind, Enemies in War, in Peace Friends.\n" "We, therefore, the Representatives of the united States of America, in General Congress, Assembled, appealing to the Supreme Judge of the world for the rectitude of " "our intentions, do, in the Name, and by Authority of the good People of these Colonies, solemnly publish and declare, That these United Colonies are, and of Right ought " "to be Free and Independent States; that they are Absolved from all Allegiance to the British Crown, and that all political connection between them and the State of Great " "Britain, is and ought to be totally dissolved; and that as Free and Independent States, they have full Power to levy War, conclude Peace, contract Alliances, establish " "Commerce, and to do all other Acts and Things which Independent States may of right do. And for the support of this Declaration, with a firm reliance on the protection of " "divine Providence, we mutually pledge to each other our Lives, our Fortunes and our sacred Honor.")
Some default text to use if standard input isn't used.
AUDIOBYTES_MAX_48K
static const uint32_t AUDIOBYTES_MAX_48K(201 *1024)
The maximum number of bytes of 48KHz audio that can be transferred for a single frame....
ancillarylist.h
Declares the AJAAncillaryList class.
AJA_STATUS_BUSY
@ AJA_STATUS_BUSY
Definition: types.h:391
CNTV2DeviceScanner::GetFirstDeviceFromArgument
static bool GetFirstDeviceFromArgument(const std::string &inArgument, CNTV2Card &outDevice)
Rescans the host, and returns an open CNTV2Card instance for the AJA device that matches a command li...
Definition: ntv2devicescanner.cpp:366
AUTOCIRCULATE_STATUS::GetProcessedFrameCount
ULWord GetProcessedFrameCount(void) const
Definition: ntv2publicinterface.h:7216
NTV2MakeChannelList
NTV2ChannelList NTV2MakeChannelList(const NTV2Channel inFirstChannel, const UWord inNumChannels=1)
Definition: ntv2publicinterface.cpp:3374
CCPlayerConfig::fSuppressTimecode
bool fSuppressTimecode
If true, suppress timecode; otherwise embed VITC/LTC.
Definition: ntv2ccplayer.h:87
NTV2_AUDIOSYSTEM_1
@ NTV2_AUDIOSYSTEM_1
This identifies the first Audio System.
Definition: ntv2enums.h:3816
NTV2_IS_HFR_STANDARD
#define NTV2_IS_HFR_STANDARD(__s__)
Definition: ntv2enums.h:201
NTV2OutputDestinationToChannel
NTV2Channel NTV2OutputDestinationToChannel(const NTV2OutputDestination inOutputDest)
Converts a given NTV2OutputDestination to its equivalent NTV2Channel value.
Definition: ntv2utils.cpp:5213
CNTV2CaptionRenderer::BurnString
static bool BurnString(const std::string &inString, const NTV2Line21Attrs &inAttribs, NTV2Buffer &inFB, const NTV2FormatDesc &inFBDescriptor, const UWord inRowNum=15, const UWord inColumnNum=1)
Blits the contents of the given UTF-8 encoded string into the given host buffer using the given displ...
NTV2ACFrameRange::count
UWord count(void) const
Definition: ntv2utils.h:974
ntv2testpatterngen.h
Declares the NTV2TestPatternGen class.
CNTV2CaptionEncoder608::GetQueuedMessageCount
virtual size_t GetQueuedMessageCount(const NTV2Line21Field inFieldNum=NTV2_CC608_Field1) const
Answers with the current depth of my queue (for the given CC608 field).
CCGenConfig::fFilesToPlay
NTV2StringList fFilesToPlay
A list of zero or more strings containing paths to text files to be "played".
Definition: ntv2ccplayer.h:46
NTV2XptConnection
std::pair< NTV2InputXptID, NTV2OutputXptID > NTV2XptConnection
Definition: ntv2signalrouter.h:38
CNTV2MacDriverInterface::ReleaseStreamForApplication
virtual bool ReleaseStreamForApplication(ULWord inApplicationType, int32_t inProcessID)
Releases exclusive use of the AJA device for the given process, permitting other processes to acquire...
Definition: ntv2macdriverinterface.cpp:516
AJA_STATUS_MEMORY
@ AJA_STATUS_MEMORY
Definition: types.h:397
timecode.h
Declares the AJATimeCode class.
NTV2_IS_VANCMODE_OFF
#define NTV2_IS_VANCMODE_OFF(__v__)
Definition: ntv2enums.h:3728
NTV2Buffer::Allocate
bool Allocate(const size_t inByteCount, const bool inPageAligned=false)
Allocates (or re-allocates) my user-space storage using the given byte count. I assume full responsib...
Definition: ntv2publicinterface.cpp:1630
CCPlayerConfig::fCapChanGenConfigs
CaptionChanGenMap fCapChanGenConfigs
Caption channel generator configs.
Definition: ntv2ccplayer.h:90
CCGenConfig::fCaptionChannel
NTV2Line21Channel fCaptionChannel
The caption channel to use.
Definition: ntv2ccplayer.h:49
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:730
PlayerConfig::fDoMultiFormat
bool fDoMultiFormat
If true, enable device-sharing; otherwise take exclusive control of device.
Definition: ntv2democommon.h:323
CNTV2Card::ApplySignalRoute
virtual bool ApplySignalRoute(const CNTV2SignalRouter &inRouter, const bool inReplace=(0))
Applies the given routing table to the AJA device.
Definition: ntv2regroute.cpp:242
TimecodeFormat
TimecodeFormat
Definition: ntv2rp188.h:27
SCCSource::~SCCSource
virtual ~SCCSource()
Definition: ntv2ccplayer.cpp:634
PlayerConfig::fVancMode
NTV2VANCMode fVancMode
VANC mode to use.
Definition: ntv2democommon.h:320
CNTV2Card::SetAudioLoopBack
virtual bool SetAudioLoopBack(const NTV2AudioLoopBack inMode, const NTV2AudioSystem inAudioSystem=NTV2_AUDIOSYSTEM_1)
Enables or disables NTV2AudioLoopBack mode for the given NTV2AudioSystem.
Definition: ntv2audio.cpp:300
NTV2_CHANNEL1
@ NTV2_CHANNEL1
Specifies channel or Frame Store 1 (or the first item).
Definition: ntv2enums.h:1307
AUTOCIRCULATE_TRANSFER::SetOutputTimeCode
bool SetOutputTimeCode(const NTV2_RP188 &inTimecode, const NTV2TCIndex inTCIndex=NTV2_TCINDEX_SDI1)
Intended for playout, sets one element of my acOutputTimeCodes member.
Definition: ntv2publicinterface.cpp:2755
ntv2debug.h
CNTV2Card::SetFrameBufferFormat
virtual bool SetFrameBufferFormat(NTV2Channel inChannel, NTV2FrameBufferFormat inNewFormat, bool inIsAJARetail=(!(0)), NTV2HDRXferChars inXferChars=NTV2_VPID_TC_SDR_TV, NTV2HDRColorimetry inColorimetry=NTV2_VPID_Color_Rec709, NTV2HDRLuminance inLuminance=NTV2_VPID_Luminance_YCbCr)
Sets the frame buffer format for the given FrameStore on the AJA device.
Definition: ntv2register.cpp:1812
CNTV2Card::SetSDITransmitEnable
virtual bool SetSDITransmitEnable(const NTV2Channel inChannel, const bool inEnable)
Sets the specified bidirectional SDI connector to act as an input or an output.
Definition: ntv2register.cpp:3796
AsSCCSource
#define AsSCCSource(__x__)
Definition: ntv2ccplayer.cpp:39
CaptionData::f1_char2
UByte f1_char2
Caption Byte 2 of Field 1.
Definition: ntv2caption608types.h:659
CUtf8Helpers::Utf8ToCEA608String
static std::string Utf8ToCEA608String(const std::string &inUtf8Str, const NTV2Line21Channel inChannel=NTV2_CC608_CC1)
Converts the given UTF8-encoded string into a string that can be used in the CNTV2CaptionEncoder608's...
CNTV2Card::SetVANCShiftMode
virtual bool SetVANCShiftMode(NTV2Channel inChannel, NTV2VANCDataShiftMode inMode)
Enables or disables the "VANC Shift Mode" feature for the given channel.
Definition: ntv2register.cpp:2800
AUTOCIRCULATE_STATUS::CanAcceptMoreOutputFrames
bool CanAcceptMoreOutputFrames(void) const
Definition: ntv2publicinterface.h:7231
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:1200
CNTV2CaptionEncoder608::GetDequeueByteTally
virtual size_t GetDequeueByteTally(void) const
Returns the total number of bytes (including command bytes) that have been dequeued from me since I w...
Definition: ntv2captionencoder608.h:329
NTV2CCPlayer::SetUpBackgroundPatternBuffer
virtual AJAStatus SetUpBackgroundPatternBuffer(void)
Sets up my gray background field.
Definition: ntv2ccplayer.cpp:1018
NTV2_FIELD0
@ NTV2_FIELD0
Identifies the first field in time for an interlaced video frame, or the first and only field in a pr...
Definition: ntv2enums.h:1787
CCGenConfig::Get
AJALabelValuePairs Get(void) const
Definition: ntv2ccplayer.cpp:211
nlohmann::json_abiNLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON_v3_11_NLOHMANN_JSON_VERSION_PATCH::detail::void
j template void())
Definition: json.hpp:4893
DeviceCapabilities::CanDoOutputDestination
bool CanDoOutputDestination(const NTV2OutputDestination inDest)
Definition: ntv2devicecapabilities.h:242
NTV2_FRAMERATE_2500
@ NTV2_FRAMERATE_2500
25 frames per second
Definition: ntv2enums.h:404
AJAAncillaryList
I am an ordered collection of AJAAncillaryData instances which represent one or more SMPTE 291 data p...
Definition: ancillarylist.h:64
NTV2_HDMIAudio8Channels
@ NTV2_HDMIAudio8Channels
8 audio channels
Definition: ntv2enums.h:3589
NTV2FrameRate
NTV2FrameRate
Identifies a particular video frame rate.
Definition: ntv2enums.h:396
CNTV2CaptionEncoder708::GetSMPTE334Data
virtual const UWord * GetSMPTE334Data(void) const
Definition: ntv2captionencoder708.h:735
NTV2CCPlayer::PlayThreadStatic
static void PlayThreadStatic(AJAThread *pThread, void *pContext)
This is the playout thread's static callback function that gets called when the playout thread runs....
Definition: ntv2ccplayer.cpp:1562
CNTV2CaptionEncoder608::GetHighestQueueDepth
virtual size_t GetHighestQueueDepth(void) const
Returns the highest queue depth – i.e., the maximum number of messages I held in either of my queues ...
Definition: ntv2captionencoder608.h:345
SCCSource::EnqueueCCDataToFrame
virtual bool EnqueueCCDataToFrame(CNTV2CaptionEncoder608Ptr inEncoder, const uint32_t inFrameNum)
Enqueues next-available CC data into the given encoder for the given frame number.
Definition: ntv2ccplayer.cpp:735
CapGenStartInfo
Definition: ntv2ccplayer.cpp:1364
NTV2_IS_4K_VIDEO_FORMAT
#define NTV2_IS_4K_VIDEO_FORMAT(__f__)
Definition: ntv2enums.h:746
IsProgressivePicture
bool IsProgressivePicture(const NTV2VideoFormat format)
Definition: ntv2utils.cpp:5423
NTV2_CHANNEL4
@ NTV2_CHANNEL4
Specifies channel or Frame Store 4 (or the 4th item).
Definition: ntv2enums.h:1310
PlayerConfig::fDoTsiRouting
bool fDoTsiRouting
If true, enable TSI routing; otherwise route for square division (4K/8K)
Definition: ntv2democommon.h:329
NTV2_CHANNEL5
@ NTV2_CHANNEL5
Specifies channel or Frame Store 5 (or the 5th item).
Definition: ntv2enums.h:1311
NTV2CCPlayer::StartPlayoutThread
virtual void StartPlayoutThread(void)
Starts my playout thread.
Definition: ntv2ccplayer.cpp:1552
CNTV2Card::features
virtual class DeviceCapabilities & features(void)
Definition: ntv2card.h:141
AJAThread
Definition: thread.h:69
AUTOCIRCULATE_WITH_ANC
#define AUTOCIRCULATE_WITH_ANC
Use this to AutoCirculate with ancillary data.
Definition: ntv2publicinterface.h:5527
AJAThread::Active
virtual bool Active()
Definition: thread.cpp:116
NTV2CCPlayer::Init
virtual AJAStatus Init(void)
Initializes me and prepares me to Run.
Definition: ntv2ccplayer.cpp:944
operator<<
std::ostream & operator<<(std::ostream &ioStrm, const CCPlayerConfig &inObj)
Definition: ntv2ccplayer.cpp:248
CNTV2CaptionEncoder708::GetSMPTE334Size
virtual size_t GetSMPTE334Size(void) const
Definition: ntv2captionencoder708.h:736
CNTV2Card::GetDisplayName
virtual std::string GetDisplayName(void)
Answers with this device's display name.
Definition: ntv2card.cpp:86
NTV2_AUTOCIRCULATE_INVALID
@ NTV2_AUTOCIRCULATE_INVALID
Definition: ntv2publicinterface.h:4279
AJAStatus
AJAStatus
Definition: types.h:378
ntv2ccplayer.h
process.h
Declares the AJAProcess class.
PlayerConfig::fFrames
NTV2ACFrameRange fFrames
AutoCirculate frame count or range.
Definition: ntv2democommon.h:317
NTV2_CC608_White
@ NTV2_CC608_White
Definition: ntv2caption608types.h:155
CNTV2Card::SetHDMIOutAudioChannels
virtual bool SetHDMIOutAudioChannels(const NTV2HDMIAudioChannels inNewValue)
Definition: ntv2audio.cpp:851
CCGenConfig::fEndAction
AtEndAction fEndAction
The action to take after the file list has finished playing.
Definition: ntv2ccplayer.h:47
NTV2_CC608_Magenta
@ NTV2_CC608_Magenta
Definition: ntv2caption608types.h:161
AJATime::Sleep
static void Sleep(const int32_t inMilliseconds)
Suspends execution of the current thread for a given number of milliseconds.
Definition: systemtime.cpp:284
CCPlayerConfig::fEmitStats
bool fEmitStats
If true, show stats while playing; otherwise echo caption text being played.
Definition: ntv2ccplayer.h:83
nlohmann::json_abiNLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON_v3_11_NLOHMANN_JSON_VERSION_PATCH::detail::value_t::string
@ string
string value
CNTV2Card::SetSDIOutputAudioSystem
virtual bool SetSDIOutputAudioSystem(const NTV2Channel inSDIOutputConnector, const NTV2AudioSystem inAudioSystem)
Sets the device's NTV2AudioSystem that will provide audio for the given SDI output's audio embedder....
Definition: ntv2register.cpp:3949
AJATimeBase
Definition: timebase.h:18
AJA_STATUS_FEATURE
@ AJA_STATUS_FEATURE
Definition: types.h:393
AJA_STATUS_FAIL
@ AJA_STATUS_FAIL
Definition: types.h:382
ULWord
uint32_t ULWord
Definition: ajatypes.h:253
AJAAncillaryData_Cea708
This class handles CEA-708 SMPTE 334 packets.
Definition: ancillarydata_cea708.h:23
CNTV2Card::EnableChannels
virtual bool EnableChannels(const NTV2ChannelSet &inChannels, const bool inDisableOthers=(0))
Enables the given FrameStore(s).
Definition: ntv2register.cpp:2107
NTV2_VANCDATA_8BITSHIFT_ENABLE
@ NTV2_VANCDATA_8BITSHIFT_ENABLE
Definition: ntv2enums.h:3736
AJASystemInfo::append
static AJALabelValuePairs & append(AJALabelValuePairs &inOutTable, const std::string &inLabel, const std::string &inValue=std::string())
A convenience function that appends the given label and value strings to the provided AJALabelValuePa...
Definition: info.h:168
AJAAncDataHorizOffset_AnyVanc
#define AJAAncDataHorizOffset_AnyVanc
VANC – Packet placed/found in any legal area of raster line after SAV, but before EAV.
Definition: ancillarydata.h:212
NTV2_CC608_Field2
@ NTV2_CC608_Field2
Definition: ntv2caption608types.h:60
NTV2_CC608_ChannelInvalid
@ NTV2_CC608_ChannelInvalid
Definition: ntv2caption608types.h:98
ntv2devicescanner.h
Declares the CNTV2DeviceScanner class.
NTV2_IS_625_FORMAT
#define NTV2_IS_625_FORMAT(__f__)
Definition: ntv2enums.h:873
AJAAncDataChannel_Y
@ AJAAncDataChannel_Y
The ancillary data is associated with the luminance (Y) channel of the video stream.
Definition: ancillarydata.h:133
PlayerConfig::fSuppressAudio
bool fSuppressAudio
If true, suppress audio; otherwise generate audio tone.
Definition: ntv2democommon.h:324
CCPlayerConfig::fSuppress608
bool fSuppress608
If true, don't transmit CEA608 packets; otherwise include 608 packets.
Definition: ntv2ccplayer.h:85
CNTV2CaptionEncoder608::EnqueueRollUpMessage
virtual bool EnqueueRollUpMessage(const std::string &inMessageStr, const NTV2Line21Mode inRollMode=NTV2_CC608_CapModeRollUp4, const NTV2Line21Channel inChannel=NTV2_CC608_CC1, const UWord inRowNumber=NTV2_CC608_MaxRow, const UWord inColumnNumber=NTV2_CC608_MinCol, const NTV2Line21Attrs &inDisplayAttribs=NTV2Line21Attrs())
Enqueues the given message for eventual "roll up" display.
AUTOCIRCULATE_TRANSFER::SetOutputTimeCodes
bool SetOutputTimeCodes(const NTV2TimeCodes &inValues)
Intended for playout, replaces the contents of my acOutputTimeCodes member.
Definition: ntv2publicinterface.cpp:2735
CNTV2DemoCommon::SetDefaultPageSize
static size_t SetDefaultPageSize(void)
Definition: ntv2democommon.cpp:1484
NTV2ChannelToTimecodeIndex
NTV2TCIndex NTV2ChannelToTimecodeIndex(const NTV2Channel inChannel, const bool inEmbeddedLTC=false, const bool inIsF2=false)
Converts the given NTV2Channel value into the equivalent NTV2TCIndex value.
Definition: ntv2utils.cpp:5020
CCGenConfig
This class is used to configure a caption generator for a single caption channel.
Definition: ntv2ccplayer.h:43
IsLine21CaptionChannel
#define IsLine21CaptionChannel(_chan_)
Definition: ntv2caption608types.h:103
CNTV2Card::SetSDIOutRGBLevelAConversion
virtual bool SetSDIOutRGBLevelAConversion(const UWord inOutputSpigot, const bool inEnable)
Enables or disables an RGB-over-3G-level-A conversion at the SDI output widget (assuming the AJA devi...
Definition: ntv2register.cpp:4347
IsValidLine21Channel
#define IsValidLine21Channel(_chan_)
Definition: ntv2caption608types.h:102
GetCSCOutputXptFromChannel
NTV2OutputXptID GetCSCOutputXptFromChannel(const NTV2Channel inCSC, const bool inIsKey=false, const bool inIsRGB=false)
Definition: ntv2signalrouter.cpp:819
NTV2Line21ModeToStr
const std::string & NTV2Line21ModeToStr(const NTV2Line21Mode inLine21Mode)
Converts the given NTV2Line21Mode value into a human-readable string.
AJASystemInfo::ToString
virtual void ToString(std::string &outAllLabelsAndValues) const
Answers with a multi-line string that contains the complete host system info table.
AJAProcess::GetPid
static uint64_t GetPid()
Definition: process.cpp:35
CNTV2CaptionEncoder608::EnqueuePopOnMessage
virtual bool EnqueuePopOnMessage(const std::string &inMessageStr, const NTV2Line21Channel inChannel=NTV2_CC608_CC1, const UWord inRowNumber=0, const UWord inColumnNumber=0, const NTV2Line21Attrs &inDisplayAttribs=NTV2Line21Attrs())
Enqueues the given message for eventual "pop-on" display.
AtEndAction_Repeat
@ AtEndAction_Repeat
Terminate.
Definition: ntv2ccplayer.h:30
CaptionSource::GetNextCaptionCharacter
virtual string GetNextCaptionCharacter(void)
Returns the next character read from my input stream. If my text input stream has reached EOF,...
Definition: ntv2ccplayer.cpp:328
CNTV2Card::UnsubscribeOutputVerticalEvent
virtual bool UnsubscribeOutputVerticalEvent(const NTV2Channel inChannel)
Unregisters me so I'm no longer notified when an output VBI is signaled on the given output channel.
Definition: ntv2subscriptions.cpp:61
UWord
uint16_t UWord
Definition: ajatypes.h:251
PlayerConfig::fVideoFormat
NTV2VideoFormat fVideoFormat
The video format to use.
Definition: ntv2democommon.h:319
NTV2CCPlayer::RouteOutputSignal
virtual AJAStatus RouteOutputSignal(void)
Sets up signal routing for playout.
Definition: ntv2ccplayer.cpp:1189
CNTV2Card::AutoCirculateGetStatus
virtual bool AutoCirculateGetStatus(const NTV2Channel inChannel, AUTOCIRCULATE_STATUS &outStatus)
Returns the current AutoCirculate status for the given channel.
Definition: ntv2autocirculate.cpp:646
NTV2_IS_VANCMODE_ON
#define NTV2_IS_VANCMODE_ON(__v__)
Definition: ntv2enums.h:3727
NTV2_FBF_8BIT_YCBCR
@ NTV2_FBF_8BIT_YCBCR
See 8-Bit YCbCr Format.
Definition: ntv2enums.h:211
NTV2_REFERENCE_FREERUN
@ NTV2_REFERENCE_FREERUN
Specifies the device's internal clock.
Definition: ntv2enums.h:1404
CNTV2CaptionEncoder708::Create
static bool Create(CNTV2CaptionEncoder708Ptr &outEncoder)
Creates a new CNTV2CaptionEncoder708 instance.
AUTOCIRCULATE_TRANSFER
This object specifies the information that will be transferred to or from the AJA device in the CNTV2...
Definition: ntv2publicinterface.h:7969
PlayerConfig::fOutputChannel
NTV2Channel fOutputChannel
The device channel to use.
Definition: ntv2democommon.h:315
ntv2utils.h
Declares numerous NTV2 utility functions.
PlayerConfig::Get
AJALabelValuePairs Get(const bool inCompact=(0)) const
Renders a human-readable representation of me.
Definition: ntv2democommon.cpp:1694
GetCaptionSources
static CaptionSourceList GetCaptionSources(const NTV2StringList &inFilesToPlay, const double inCharsPerMinute)
Creates and returns a list of CaptionSource instances to play from a given list of paths to text file...
Definition: ntv2ccplayer.cpp:795
NTV2VideoFormatToString
std::string NTV2VideoFormatToString(const NTV2VideoFormat inValue, const bool inUseFrameRate=false)
Definition: ntv2utils.cpp:6750
CCPlayerConfig::fSuppressLine21
bool fSuppressLine21
SD output only: if true, do not encode Line 21 waveform; otherwise encode Line 21 waveform.
Definition: ntv2ccplayer.h:84
AJATimeCode::SetHmsf
void SetHmsf(uint32_t h, uint32_t m, uint32_t s, uint32_t f, const AJATimeBase &timeBase, bool bDropFrame)
Definition: timecode.cpp:284
AUTOCIRCULATE_TRANSFER::SetVideoBuffer
bool SetVideoBuffer(ULWord *pInVideoBuffer, const ULWord inVideoByteCount)
Sets my video buffer for use in a subsequent call to CNTV2Card::AutoCirculateTransfer.
Definition: ntv2publicinterface.cpp:2708
GetCSCInputXptFromChannel
NTV2InputXptID GetCSCInputXptFromChannel(const NTV2Channel inCSC, const bool inIsKeyInput=false)
Definition: ntv2signalrouter.cpp:775
CNTV2Card
I interrogate and control an AJA video/audio capture/playout device.
Definition: ntv2card.h:28
NTV2_CC608_XDS
@ NTV2_CC608_XDS
Definition: ntv2caption608types.h:95
NTV2_CC608_CapModeRollUp4
@ NTV2_CC608_CapModeRollUp4
4-row roll-up from bottom
Definition: ntv2caption608types.h:130
AJAAncillaryList::AddAncillaryData
virtual AJAStatus AddAncillaryData(const AJAAncillaryList &inPackets)
Appends a copy of the given list's packets to me.
Definition: ancillarylist.cpp:317
NTV2_CC608_Green
@ NTV2_CC608_Green
Definition: ntv2caption608types.h:156
CNTV2DriverInterface::IsDeviceReady
virtual bool IsDeviceReady(const bool inCheckValid=(0))
Definition: ntv2driverinterface.cpp:1284
CaptionData::bGotField2Data
bool bGotField2Data
True if Field 2 bytes have been set; otherwise false.
Definition: ntv2caption608types.h:661
CNTV2CaptionEncoder608::GetQueuedByteCount
virtual size_t GetQueuedByteCount(const NTV2Line21Field inFieldNum=NTV2_CC608_Field1) const
Answers with the total number of bytes (including command bytes) that are currently queued (for the g...
NTV2ChannelSet
std::set< NTV2Channel > NTV2ChannelSet
A set of distinct NTV2Channel values.
Definition: ntv2publicinterface.h:3854
AUTOCIRCULATE_TRANSFER::acANCField2Buffer
NTV2Buffer acANCField2Buffer
The host "Field 2" ancillary data buffer. This field is owned by the client application,...
Definition: ntv2publicinterface.h:8006
CNTV2Card::SetTsiFrameEnable
virtual bool SetTsiFrameEnable(const bool inIsEnabled, const NTV2Channel inChannel)
Enables or disables SMPTE 425 two-sample interleave (Tsi) frame mode on the device.
Definition: ntv2register.cpp:1311
gBuiltInStream
static istringstream gBuiltInStream(gBuiltInCaptions)
The global built-in caption data input stream.
CRP188
Definition: ntv2rp188.h:55
CapGenStartInfo::fCapChannel
NTV2Line21Channel fCapChannel
Definition: ntv2ccplayer.cpp:1367
CNTV2Card::SetEveryFrameServices
virtual bool SetEveryFrameServices(const NTV2EveryFrameTaskMode inMode)
Sets the device's task mode.
Definition: ntv2register.cpp:179
NTV2StringList
std::vector< std::string > NTV2StringList
Definition: ntv2utils.h:1134
NTV2CCPlayer::~NTV2CCPlayer
virtual ~NTV2CCPlayer(void)
Definition: ntv2ccplayer.cpp:878
AJA_STATUS_UNSUPPORTED
@ AJA_STATUS_UNSUPPORTED
Definition: types.h:394
IsLine21TextChannel
#define IsLine21TextChannel(_chan_)
Definition: ntv2caption608types.h:104
PLDBG
#define PLDBG(_xpr_)
Definition: ntv2democommon.h:38
NTV2_OUTPUT_DEST_IS_SDI
#define NTV2_OUTPUT_DEST_IS_SDI(_dest_)
Definition: ntv2enums.h:1294
GetSmpteLineNumber
NTV2SmpteLineNumber GetSmpteLineNumber(const NTV2Standard inStandard)
For the given video standard, returns the SMPTE-designated line numbers for Field 1 and Field 2 that ...
Definition: ntv2utils.h:955
AJA_NULL
#define AJA_NULL
Definition: ajatypes.h:197
AUTOCIRCULATE_TRANSFER::acTransferStatus
AUTOCIRCULATE_TRANSFER_STATUS acTransferStatus
Contains status information that's valid after CNTV2Card::AutoCirculateTransfer returns,...
Definition: ntv2publicinterface.h:8021
AddAudioTone
bool AddAudioTone(ULWord &outNumBytesWritten, NTV2Buffer &inAudioBuffer, ULWord &inOutCurrentSample, const ULWord inNumSamples, const double inSampleRate, const double inAmplitude, const double inFrequency, const ULWord inNumBits, const bool inByteSwap, const ULWord inNumChannels)
Fills the given buffer with 32-bit (ULWord) audio tone samples.
Definition: ntv2utils.cpp:4478
NTV2_DISABLE_TASKS
@ NTV2_DISABLE_TASKS
0: Disabled: Device is completely configured by controlling application(s) – no driver involvement.
Definition: ntv2publicinterface.h:4290
CNTV2DemoCommon::GetAJAFrameRate
static AJA_FrameRate GetAJAFrameRate(const NTV2FrameRate inFrameRate)
Definition: ntv2democommon.cpp:1011
CNTV2CaptionEncoder608::GetEnqueueByteTally
virtual size_t GetEnqueueByteTally(void) const
Returns the total number of bytes (including command bytes) that have been enqueued onto me since I w...
Definition: ntv2captionencoder608.h:323
CNTV2Card::RemoveConnections
virtual bool RemoveConnections(const NTV2XptConnections &inConnections)
Removes the given widget routing connections from the AJA device.
Definition: ntv2regroute.cpp:268
CNTV2CaptionEncoder608::Flush
virtual void Flush(const NTV2Line21Field inFieldNum=NTV2_CC608_Field1, const bool inAlsoInProgress=true)
Flushes all queued command bytes for the given CC608 field.
AJALabelValuePairsConstIter
AJALabelValuePairs::const_iterator AJALabelValuePairsConstIter
Definition: info.h:70
SignalHandler
static void SignalHandler(int inSignal)
Definition: main.cpp:23
NTV2TestPatternGen
The NTV2 test pattern generator.
Definition: ntv2testpatterngen.h:69
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:1325
CapGenStartInfo::fSpare
uint32_t fSpare
Definition: ntv2ccplayer.cpp:1368
NTV2ChannelList
std::vector< NTV2Channel > NTV2ChannelList
An ordered sequence of NTV2Channel values.
Definition: ntv2publicinterface.h:3835
NTV2Buffer::GetHostPointer
void * GetHostPointer(void) const
Definition: ntv2publicinterface.h:6049
NTV2_CC608_CapModeRollUp2
@ NTV2_CC608_CapModeRollUp2
2-row roll-up from bottom
Definition: ntv2caption608types.h:128
NTV2_IS_QUAD_QUAD_FORMAT
#define NTV2_IS_QUAD_QUAD_FORMAT(__f__)
Definition: ntv2enums.h:778
CNTV2CaptionEncoder708::Set608CaptionData
virtual bool Set608CaptionData(const CaptionData &inCC608Data)
Sets the CEA-608 caption data in my private 608 data buffer.
ntv2captionrenderer.h
Declares the CNTV2CaptionRenderer class.
CNTV2CaptionEncoder608::Erase
virtual bool Erase(const NTV2Line21Channel inChannel=NTV2_CC608_CC1)
Clears captions on the given channel by emitting ENM (Erase Non-displayed Memory) and EOC (End Of Cap...
NTV2_FBF_10BIT_YCBCR
@ NTV2_FBF_10BIT_YCBCR
See 10-Bit YCbCr Format.
Definition: ntv2enums.h:210
AJA_STATUS_INITIALIZE
@ AJA_STATUS_INITIALIZE
Definition: types.h:386
NTV2_VANCMODE_TALLER
@ NTV2_VANCMODE_TALLER
This identifies the mode in which there are some + extra VANC lines in the frame buffer.
Definition: ntv2enums.h:3720
AJAAncillaryData_Cea608_Vanc::GeneratePayloadData
virtual AJAStatus GeneratePayloadData(void)
Generate the payload data from my "local" ancillary data.
Definition: ancillarydata_cea608_vanc.cpp:120
CapGenStartInfo::fpPlayer
NTV2CCPlayer * fpPlayer
Definition: ntv2ccplayer.cpp:1366
PlayerConfig::fDoRGBOnWire
bool fDoRGBOnWire
If true, produce RGB on the wire; otherwise output YUV.
Definition: ntv2democommon.h:330
NTV2SmpteLineNumber
Used to describe Start of Active Video (SAV) location and field dominance for a given NTV2Standard....
Definition: ntv2utils.h:869
SCCSource::SCCSource
SCCSource(const double inCharsPerMinute, istream *pInInputStream, const string &inFilePath, const bool inDeleteInputStream=(0))
Definition: ntv2ccplayer.cpp:660
DEC
#define DEC(__x__)
Definition: ntv2publicinterface.h:5605
AJAAncillaryData::SetLocationLineNumber
virtual AJAStatus SetLocationLineNumber(const uint16_t inLineNum)
Sets my ancillary data "location" frame line number.
Definition: ancillarydata.cpp:321
NTV2Line21ChannelToStr
const std::string & NTV2Line21ChannelToStr(const NTV2Line21Channel inLine21Channel, const bool inCompact=true)
Converts the given NTV2Line21Channel value into a human-readable string.
PlayerConfig::fOutputDest
NTV2OutputDest fOutputDest
The desired output connector to use.
Definition: ntv2democommon.h:316
NTV2Line21Mode
NTV2Line21Mode
The CEA-608 modes: pop-on, roll-up (2, 3 and 4-line), and paint-on.
Definition: ntv2caption608types.h:123
NTV2_FRAMERATE_5994
@ NTV2_FRAMERATE_5994
Fractional rate of 60,000 frames per 1,001 seconds.
Definition: ntv2enums.h:401
false
#define false
Definition: ntv2devicefeatures.h:25
ntv2democommon.h
This file contains some structures, constants, classes and functions that are used in some of the dem...
common.h
Private include file for all ajabase sources.
UByte
uint8_t UByte
Definition: ajatypes.h:248
AUTOCIRCULATE_WITH_RP188
#define AUTOCIRCULATE_WITH_RP188
Use this to AutoCirculate with RP188.
Definition: ntv2publicinterface.h:5521
NTV2FormatDescriptor::GetWriteableRowAddress
void * GetWriteableRowAddress(void *pInStartAddress, const ULWord inRowIndex0, const UWord inPlaneIndex0=0) const
Definition: ntv2formatdescriptor.cpp:1018
NTV2CCPlayer::CaptionGeneratorThreadStatic
static void CaptionGeneratorThreadStatic(AJAThread *pThread, void *pContext)
This is the caption generator thread's static callback function that gets called when the caption gen...
Definition: ntv2ccplayer.cpp:1390
NTV2ACFrameRange::lastFrame
UWord lastFrame(void) const
Definition: ntv2utils.h:976
AUTOCIRCULATE_TRANSFER_STATUS::acState
NTV2AutoCirculateState acState
Current AutoCirculate state after the transfer.
Definition: ntv2publicinterface.h:7882
GetFrameBufferOutputXptFromChannel
NTV2OutputXptID GetFrameBufferOutputXptFromChannel(const NTV2Channel inFrameStore, const bool inIsRGB=false, const bool inIs425=false)
Definition: ntv2signalrouter.cpp:845
CRP188::GetRP188CString
const char * GetRP188CString() const
Definition: ntv2rp188.cpp:924
ancillarydata_cea608_vanc.h
Declares the AJAAncillaryData_Cea608_Vanc class.
NTV2FrameBufferFormatToString
std::string NTV2FrameBufferFormatToString(const NTV2FrameBufferFormat inValue, const bool inForRetailDisplay=false)
Definition: ntv2utils.cpp:6940
PlayerConfig::fDeviceSpec
std::string fDeviceSpec
The AJA device to use.
Definition: ntv2democommon.h:313
IsField1Line21CaptionChannel
#define IsField1Line21CaptionChannel(_chan_)
Definition: ntv2caption608types.h:106
videotypes.h
Declares the enumeration constants used in the ajabase library.
GetTSIMuxOutputXptFromChannel
NTV2OutputXptID GetTSIMuxOutputXptFromChannel(const NTV2Channel inTSIMuxer, const bool inLinkB=false, const bool inIsRGB=false)
Definition: ntv2signalrouter.cpp:1005
NTV2TimeCodes
std::map< NTV2TCIndex, NTV2_RP188 > NTV2TimeCodes
A mapping of NTV2TCIndex enum values to NTV2_RP188 structures.
Definition: ntv2publicinterface.h:6846
AJA_STATUS_BAD_PARAM
@ AJA_STATUS_BAD_PARAM
Definition: types.h:392
NTV2Line21Channel
NTV2Line21Channel
The CEA-608 caption channels: CC1 thru CC4, TX1 thru TX4, plus XDS.
Definition: ntv2caption608types.h:82
CNTV2Card::WaitForOutputVerticalInterrupt
virtual bool WaitForOutputVerticalInterrupt(const NTV2Channel inChannel=NTV2_CHANNEL1, UWord inRepeatCount=1)
Efficiently sleeps the calling thread/process until the next one or more field (interlaced video) or ...
Definition: ntv2subscriptions.cpp:134
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:1277
NTV2MakeChannelSet
NTV2ChannelSet NTV2MakeChannelSet(const NTV2Channel inFirstChannel, const UWord inNumChannels=1)
Definition: ntv2publicinterface.cpp:3357
std
Definition: json.hpp:5362
NTV2_RP188
This struct replaces the old RP188_STRUCT.
Definition: ntv2publicinterface.h:6760
NTV2_TCINDEX_LTC2
@ NTV2_TCINDEX_LTC2
Analog LTC 2.
Definition: ntv2enums.h:3880
IsRGBFormat
bool IsRGBFormat(const NTV2FrameBufferFormat format)
Definition: ntv2utils.cpp:5442
CCPlayerConfig::fTestPatternName
std::string fTestPatternName
The test pattern to use.
Definition: ntv2ccplayer.h:89
CNTV2CaptionEncoder608::EnqueueTextMessage
virtual bool EnqueueTextMessage(const std::string &inMessageStr, const bool inEraseFirst=false, const NTV2Line21Channel inChannel=NTV2_CC608_Text1)
Enqueues the given message for eventual reception and possible display on a receiver capable of displ...
AJATimeCode::QueryFrame
uint32_t QueryFrame(void) const
Definition: timecode.cpp:94
NTV2_FRAMERATE_UNKNOWN
@ NTV2_FRAMERATE_UNKNOWN
Represents an unknown or invalid frame rate.
Definition: ntv2enums.h:398
CNTV2Card::AutoCirculateTransfer
virtual bool AutoCirculateTransfer(const NTV2Channel inChannel, AUTOCIRCULATE_TRANSFER &transferInfo)
Transfers all or part of a frame as specified in the given AUTOCIRCULATE_TRANSFER object to/from the ...
Definition: ntv2autocirculate.cpp:695
ULWordSequence
std::vector< uint32_t > ULWordSequence
An ordered sequence of ULWord (uint32_t) values.
Definition: ntv2publicinterface.h:46
AUTOCIRCULATE_STATUS::GetDroppedFrameCount
ULWord GetDroppedFrameCount(void) const
Definition: ntv2publicinterface.h:7211
GetAudioSamplesPerFrame
ULWord GetAudioSamplesPerFrame(const NTV2FrameRate inFrameRate, const NTV2AudioRate inAudioRate, ULWord inCadenceFrame=0, bool inIsSMPTE372Enabled=false)
Returns the number of audio samples for a given video frame rate, audio sample rate,...
Definition: ntv2utils.cpp:2789
CNTV2Card::AutoCirculateInitForOutput
virtual bool AutoCirculateInitForOutput(const NTV2Channel inChannel, const UWord inFrameCount=7, const NTV2AudioSystem inAudioSystem=NTV2_AUDIOSYSTEM_INVALID, const ULWord inOptionFlags=0, const UByte inNumChannels=1, const UWord inStartFrameNumber=0, const UWord inEndFrameNumber=0)
Prepares for subsequent AutoCirculate playout, designating a contiguous block of frame buffers on the...
Definition: ntv2autocirculate.cpp:353
NTV2_CC608_CapModeRollUp3
@ NTV2_CC608_CapModeRollUp3
3-row roll-up from bottom
Definition: ntv2caption608types.h:129
NTV2_TCINDEX_DEFAULT
@ NTV2_TCINDEX_DEFAULT
The "default" timecode (mostly used by the AJA "Retail" service and Control Panel)
Definition: ntv2enums.h:3872
NTV2Line21Attrs
struct NTV2Line21Attributes NTV2Line21Attrs
Bouncer
A handy class that makes it easy to "bounce" an unsigned integer value between a minimum and maximum ...
Definition: ntv2democommon.h:167
AUTOCIRCULATE_WITH_LTC
#define AUTOCIRCULATE_WITH_LTC
Use this to AutoCirculate with analog LTC.
Definition: ntv2publicinterface.h:5522
CNTV2MacDriverInterface::AcquireStreamForApplication
virtual bool AcquireStreamForApplication(ULWord inApplicationType, int32_t inProcessID)
Reserves exclusive use of the AJA device for a given process, preventing other processes on the host ...
Definition: ntv2macdriverinterface.cpp:481
CNTV2Card::SetSDIOutputDS2AudioSystem
virtual bool SetSDIOutputDS2AudioSystem(const NTV2Channel inSDIOutputConnector, const NTV2AudioSystem inAudioSystem)
Sets the Audio System that will supply audio for the given SDI output's audio embedder for Data Strea...
Definition: ntv2register.cpp:4006
CaptionSource::CaptionSource
CaptionSource(const double inCharsPerMinute, istream *pInInputStream, const string &inFilePath, const bool inDeleteInputStream=(0))
My only constructor.
Definition: ntv2ccplayer.cpp:289
ntv2rp188.h
Declares the CRP188 class. See SMPTE RP188 standard for details.
NTV2CCPlayer::Quit
virtual void Quit(const bool inQuitImmediately=(0))
Stops me.
Definition: ntv2ccplayer.cpp:893
NTV2CCPlayer::GenerateCaptions
virtual void GenerateCaptions(const NTV2Line21Channel inCCChannel)
This is the thread function that produces caption messages for a given caption channel.
Definition: ntv2ccplayer.cpp:1407
NTV2_AudioChannel1_8
@ NTV2_AudioChannel1_8
This selects audio channels 1 thru 8.
Definition: ntv2enums.h:3247
NTV2CCPlayer::Run
virtual AJAStatus Run(void)
Runs me.
Definition: ntv2ccplayer.cpp:1350
CNTV2DriverInterface::GetDeviceID
virtual NTV2DeviceID GetDeviceID(void)
Definition: ntv2driverinterface.cpp:381
CNTV2Card::GetDriverVersionComponents
virtual bool GetDriverVersionComponents(UWord &outMajor, UWord &outMinor, UWord &outPoint, UWord &outBuild)
Answers with the individual version components of this device's driver.
Definition: ntv2card.cpp:169
NTV2_IS_QUAD_FRAME_FORMAT
#define NTV2_IS_QUAD_FRAME_FORMAT(__f__)
Definition: ntv2enums.h:771
CNTV2Card::GetEveryFrameServices
virtual bool GetEveryFrameServices(NTV2EveryFrameTaskMode &outMode)
Retrieves the device's current "retail service" task mode.
Definition: ntv2register.cpp:184
CCPlayerConfig::fSuppress708
bool fSuppress708
If true, don't transmit CEA708 packets; otherwise include 708 packets.
Definition: ntv2ccplayer.h:86
gFrequencies
static const double gFrequencies[]
Definition: ntv2dolbyplayer.cpp:49
CNTV2Card::GetFrameRate
virtual bool GetFrameRate(NTV2FrameRate &outValue, NTV2Channel inChannel=NTV2_CHANNEL1)
Returns the AJA device's currently configured frame rate via its "value" parameter.
Definition: ntv2register.cpp:1022
NTV2StringListConstIter
NTV2StringList::const_iterator NTV2StringListConstIter
Definition: ntv2utils.h:1136
AUTOCIRCULATE_TRANSFER::acOutputTimeCodes
NTV2Buffer acOutputTimeCodes
Intended for playout, this is an ordered sequence of NTV2_RP188 values to send to the device....
Definition: ntv2publicinterface.h:8014
AJAAncillaryData_Cea608_Vanc
This class handles VANC-based CEA-608 caption data packets (not "analog" Line 21).
Definition: ancillarydata_cea608_vanc.h:26
NTV2_IS_4K_4096_VIDEO_FORMAT
#define NTV2_IS_4K_4096_VIDEO_FORMAT(__f__)
Definition: ntv2enums.h:792
NTV2_CC608_Field1
@ NTV2_CC608_Field1
Definition: ntv2caption608types.h:59
NTV2ChannelToString
std::string NTV2ChannelToString(const NTV2Channel inValue, const bool inForRetailDisplay=false)
Definition: ntv2utils.cpp:5759
CNTV2Card::SetHDMIOutAudioSource8Channel
virtual bool SetHDMIOutAudioSource8Channel(const NTV2Audio8ChannelSelect inNewValue, const NTV2AudioSystem inAudioSystem=NTV2_AUDIOSYSTEM_1)
Changes the HDMI output's 8-channel audio source.
Definition: ntv2audio.cpp:914
GetNTV2StandardFromVideoFormat
NTV2Standard GetNTV2StandardFromVideoFormat(const NTV2VideoFormat inVideoFormat)
Definition: ntv2utils.cpp:2277
PlayerConfig::fPixelFormat
NTV2PixelFormat fPixelFormat
The pixel format to use.
Definition: ntv2democommon.h:318
ancillarydata_cea708.h
Declares the AJAAncillaryData_Cea708 class.
NTV2Buffer::Fill
bool Fill(const T &inValue)
Fills me with the given scalar value.
Definition: ntv2publicinterface.h:6218
AJAThread::SetPriority
virtual AJAStatus SetPriority(AJAThreadPriority priority)
Definition: thread.cpp:133
CNTV2Card::AutoCirculateStart
virtual bool AutoCirculateStart(const NTV2Channel inChannel, const ULWord64 inStartTime=0)
Starts AutoCirculating the specified channel that was previously initialized by CNTV2Card::AutoCircul...
Definition: ntv2autocirculate.cpp:503
CaptionData::bGotField1Data
bool bGotField1Data
True if Field 1 bytes have been set; otherwise false.
Definition: ntv2caption608types.h:657
CapGenStartInfo::CapGenStartInfo
CapGenStartInfo(NTV2CCPlayer *pPlayer, const NTV2Line21Channel inCapChan)
Definition: ntv2ccplayer.cpp:1369
CNTV2Card::SetReference
virtual bool SetReference(const NTV2ReferenceSource inRefSource, const bool inKeepFramePulseSelect=(0))
Sets the device's clock reference source. See Video Output Clocking & Synchronization for more inform...
Definition: ntv2register.cpp:1484
GetDLOutInputXptFromChannel
NTV2InputXptID GetDLOutInputXptFromChannel(const NTV2Channel inDLOutWidget)
Definition: ntv2signalrouter.cpp:808
PLNOTE
#define PLNOTE(_xpr_)
Definition: ntv2democommon.h:36
CaptionSource
Definition: ntv2ccplayer.cpp:277
NTV2Line21Attributes
CEA-608 Character Attributes.
Definition: ntv2caption608types.h:357
AJA_STATUS_OPEN
@ AJA_STATUS_OPEN
Definition: types.h:388
AJAAncDataSpace_VANC
@ AJAAncDataSpace_VANC
Ancillary data found between SAV and EAV (.
Definition: ancillarydata.h:177
CaptionData
This structure encapsulates all possible CEA-608 caption data bytes that may be associated with a giv...
Definition: ntv2caption608types.h:655
CNTV2DemoCommon::NTV2FrameRate2TimecodeFormat
static TimecodeFormat NTV2FrameRate2TimecodeFormat(const NTV2FrameRate inFrameRate)
Definition: ntv2democommon.cpp:989
NTV2_FRAMERATE_5000
@ NTV2_FRAMERATE_5000
50 frames per second
Definition: ntv2enums.h:407
AJAAncillaryData::SetFromSMPTE334
virtual AJAStatus SetFromSMPTE334(const uint16_t *pInData, const uint32_t inNumWords, const AJAAncDataLoc &inLocInfo)
Copies payload data from an external 16-bit source into local payload memory.
Definition: ancillarydata.cpp:370
CNTV2Card::SetNumberAudioChannels
virtual bool SetNumberAudioChannels(const ULWord inNumChannels, const NTV2AudioSystem inAudioSystem=NTV2_AUDIOSYSTEM_1)
Sets the number of audio channels to be concurrently captured or played for a given Audio System on t...
Definition: ntv2audio.cpp:146
CNTV2Card::SetAudioBufferSize
virtual bool SetAudioBufferSize(const NTV2AudioBufferSize inValue, const NTV2AudioSystem inAudioSystem=NTV2_AUDIOSYSTEM_1)
Changes the size of the audio buffer that is used for a given Audio System in the AJA device.
Definition: ntv2audio.cpp:249
Bouncer::Next
T Next(void)
Definition: ntv2democommon.h:193
AJAThread::Start
virtual AJAStatus Start()
Definition: thread.cpp:91
CNTV2DemoCommon::StripFormatString
static std::string StripFormatString(const std::string &inStr)
Definition: ntv2democommon.cpp:933
AJA_RETAIL_DEFAULT
#define AJA_RETAIL_DEFAULT
Definition: ntv2card.h:587
NTV2_CC608_Opaque
@ NTV2_CC608_Opaque
Definition: ntv2caption608types.h:215
aja::to_string
std::string to_string(bool val)
Definition: common.cpp:180
CCGenConfig::fCharsPerMinute
double fCharsPerMinute
The rate at which caption characters get enqueued, in characters per minute.
Definition: ntv2ccplayer.h:51
CaptionData::f2_char2
UByte f2_char2
Caption Byte 2 of Field 2.
Definition: ntv2caption608types.h:663
CNTV2Line21Captioner
Instances of me can encode two ASCII characters into a "line 21" closed-captioning waveform....
Definition: ntv2line21captioner.h:34
PLFAIL
#define PLFAIL(_xpr_)
Definition: ntv2democommon.h:34
SIG_AJA_STOP
#define SIG_AJA_STOP
Definition: ntv2ccplayer.h:21
NTV2_CC608_Yellow
@ NTV2_CC608_Yellow
Definition: ntv2caption608types.h:160
NTV2CCPlayer::GetStatus
virtual void GetStatus(size_t &outMessagesQueued, size_t &outBytesQueued, size_t &outTotMsgsEnq, size_t &outTotBytesEnq, size_t &outTotMsgsDeq, size_t &outTotBytesDeq, size_t &outMaxQueDepth, size_t &outDroppedFrames) const
Returns status information from my caption encoder.
Definition: ntv2ccplayer.cpp:1825
AJALabelValuePairs
std::vector< AJALabelValuePair > AJALabelValuePairs
An ordered sequence of label/value pairs.
Definition: info.h:69
BIT
#define BIT(_x_)
Definition: ajatypes.h:561
xHEX0N
#define xHEX0N(__x__, __n__)
Definition: ntv2publicinterface.h:5604
NTV2AudioSystem
NTV2AudioSystem
Used to identify an Audio System on an NTV2 device. See Audio System Operation for more information.
Definition: ntv2enums.h:3814
AJA_FAILURE
#define AJA_FAILURE(_status_)
Definition: types.h:371
CNTV2CaptionEncoder708::MakeSMPTE334AncPacket
virtual bool MakeSMPTE334AncPacket(const NTV2FrameRate inFrameRate, const NTV2Line21Field inVideoField)
Generates a SMPTE-334 Ancillary data packet.
CaptionSource::SetTextMode
virtual void SetTextMode(const bool inIsTextMode)
Sets my text mode. If I'm in text mode, I don't do any word breaking or line/row truncation.
Definition: ntv2ccplayer.cpp:570
NTV2_TCINDEX_LTC1
@ NTV2_TCINDEX_LTC1
Analog LTC 1.
Definition: ntv2enums.h:3879
NTV2SmpteLineNumber::firstFieldTop
bool firstFieldTop
True if the first field on the wire is the top-most field in the raster (field dominance)
Definition: ntv2utils.h:873
CNTV2Line21Captioner::EncodeLine
virtual UByte * EncodeLine(const UByte inByte1, const UByte inByte2)
Encodes the two given characters as an EIA-608-compliant "line 21" waveform into my private line data...
DeviceCapabilities::CanDoFrameBufferFormat
bool CanDoFrameBufferFormat(const NTV2PixelFormat inPF)
Definition: ntv2devicecapabilities.h:223
NTV2FrameRateToString
std::string NTV2FrameRateToString(const NTV2FrameRate inValue, const bool inForRetailDisplay=false)
Definition: ntv2utils.cpp:7184
NTV2_CC608_CapModePopOn
@ NTV2_CC608_CapModePopOn
Pop-on caption mode.
Definition: ntv2caption608types.h:127
NTV2FormatDescriptor::GetFullRasterHeight
ULWord GetFullRasterHeight(void) const
Definition: ntv2formatdescriptor.h:175
NTV2ChannelToAudioSystem
NTV2AudioSystem NTV2ChannelToAudioSystem(const NTV2Channel inChannel)
Converts the given NTV2Channel value into its equivalent NTV2AudioSystem.
Definition: ntv2utils.cpp:4927
ajarefptr.h
Defines the AJARefPtr template class.
AUTOCIRCULATE_TRANSFER::acANCBuffer
NTV2Buffer acANCBuffer
The host ancillary data buffer. This field is owned by the client application, and thus is responsibl...
Definition: ntv2publicinterface.h:7995
PLINFO
#define PLINFO(_xpr_)
Definition: ntv2democommon.h:37
CNTV2Card::AutoCirculateStop
virtual bool AutoCirculateStop(const NTV2Channel inChannel, const bool inAbort=(0))
Stops AutoCirculate for the given channel, and releases the on-device frame buffers that were allocat...
Definition: ntv2autocirculate.cpp:519
GetTSIMuxInputXptFromChannel
NTV2InputXptID GetTSIMuxInputXptFromChannel(const NTV2Channel inTSIMuxer, const bool inLinkB=false)
Definition: ntv2signalrouter.cpp:993
AJAAncDataLink_A
@ AJAAncDataLink_A
The ancillary data is associated with Link A of the video stream.
Definition: ancillarydata.h:81
DEVICE_ID_NOTFOUND
@ DEVICE_ID_NOTFOUND
Invalid or "not found".
Definition: ntv2enums.h:90
PLWARN
#define PLWARN(_xpr_)
Definition: ntv2democommon.h:35
CCPlayerConfig::Get
AJALabelValuePairs Get(const bool inCompact=(0)) const
Definition: ntv2ccplayer.cpp:227
CaptionData::f1_char1
UByte f1_char1
Caption Byte 1 of Field 1.
Definition: ntv2caption608types.h:658
NTV2TestPatternGen::setVANCToLegalBlack
NTV2TestPatternGen & setVANCToLegalBlack(const bool inClearVANC)
Changes my "clear VANC lines to legal black" setting.
Definition: ntv2testpatterngen.h:198
gAmplitudes
static const double gAmplitudes[]
Definition: ntv2dolbyplayer.cpp:51
CNTV2Card::SetSDIOutLevelAtoLevelBConversion
virtual bool SetSDIOutLevelAtoLevelBConversion(const UWord inOutputSpigot, const bool inEnable)
Enables or disables 3G level A to 3G level B conversion at the SDI output widget (assuming the AJA de...
Definition: ntv2register.cpp:4315
NTV2Line21AttributesToStr
std::string NTV2Line21AttributesToStr(const NTV2Line21Attributes inLine21Attributes)
Converts the given NTV2Line21Attributes value into a human-readable string.
NTV2_FIELD1
@ NTV2_FIELD1
Identifies the last (second) field in time for an interlaced video frame.
Definition: ntv2enums.h:1788
ConvertLine_2vuy_to_v210
bool ConvertLine_2vuy_to_v210(const UByte *pInSrcLine_2vuy, ULWord *pOutDstLine_v210, const ULWord inNumPixels)
Converts a single 8-bit YCbCr '2vuy' raster line to 10-bit YCbCr 'v210' (from NTV2_FBF_8BIT_YCBCR to ...
Definition: ntv2transcode.cpp:14
CNTV2CaptionEncoder608::EnqueueCaptionData
virtual bool EnqueueCaptionData(const CaptionData &inCaptionData)
This is a low-level method that enqueues the given CaptionData for eventual transmission.
NTV2_IS_PROGRESSIVE_STANDARD
#define NTV2_IS_PROGRESSIVE_STANDARD(__s__)
Definition: ntv2enums.h:177
NTV2_OEM_TASKS
@ NTV2_OEM_TASKS
2: OEM: Device is configured by controlling application(s), with minimal driver involvement.
Definition: ntv2publicinterface.h:4292
AtEndAction_Quit
@ AtEndAction_Quit
Definition: ntv2ccplayer.h:29
GetDLOutOutputXptFromChannel
NTV2OutputXptID GetDLOutOutputXptFromChannel(const NTV2Channel inDLOutput, const bool inIsLinkB=false)
Definition: ntv2signalrouter.cpp:905
AJATime::GetSystemMilliseconds
static uint64_t GetSystemMilliseconds(void)
Returns the current value of the host's high-resolution clock, in milliseconds.
Definition: systemtime.cpp:206
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:1614
CaptionSource::GetNextCaptionWord
virtual string GetNextCaptionWord(bool &outLineBreak)
Returns the next "word" read from my input stream. If my text input stream has reached EOF,...
Definition: ntv2ccplayer.cpp:433
CaptionSourceList
deque< CaptionSourcePtr > CaptionSourceList
I am an ordered sequence of CaptionSources.
Definition: ntv2ccplayer.cpp:273
AJATimeCode
Utility class for timecodes.
Definition: timecode.h:17
CNTV2Card::SetAudioRate
virtual bool SetAudioRate(const NTV2AudioRate inRate, const NTV2AudioSystem inAudioSystem=NTV2_AUDIOSYSTEM_1)
Sets the NTV2AudioRate for the given Audio System.
Definition: ntv2audio.cpp:205
NTV2CCPlayer::NTV2CCPlayer
NTV2CCPlayer(const CCPlayerConfig &inConfigData)
Constructs me using the given configuration settings.
Definition: ntv2ccplayer.cpp:859
NTV2OutputDestinationToString
std::string NTV2OutputDestinationToString(const NTV2OutputDestination inValue, const bool inForRetailDisplay=false)
Definition: ntv2utils.cpp:7238
NTV2_AUDIOSYSTEM_INVALID
@ NTV2_AUDIOSYSTEM_INVALID
Definition: ntv2enums.h:3826