169 uint8_t luma = pLine[pixelNum];
177 static void addToCRC (
const bool inBit, uint8_t & inOutCRC)
183 newBit = (inBit ? 0 : 1);
185 newBit = (inBit ? 1 : 0);
187 inOutCRC = (inOutCRC << 1) + newBit;
204 bool bResult =
false;
207 uint8_t tcData[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
224 uint32_t currIndex = 0;
234 if (!lastPixel && thisPixel)
252 for (uint8_t group = 0; group < 9; group++)
260 for (i = 1; i < 8; i++)
280 for (i = 0; i < 8; i++)
284 currIndex += (i%2 ? 8 : 7);
287 data = (bit ? 0x80 : 0) + (data >> 1);
292 tcData[group] = data;
301 else if (CRC == 0xFF)
307 else if (CRC == 0x0F)
358 #ifdef USE_SMPTE_266M 361 static inline void DoVITCPixel (uint8_t * pOutLine,
const uint32_t inPixelNum,
const uint8_t inLevel)
363 pOutLine[inPixelNum] = inLevel;
371 if (!bBit0 && !bBit1)
379 else if (!bBit0 && bBit1)
386 else if (bBit0 && !bBit1)
406 static void DoHalfTransition (uint8_t *pLine, uint32_t& pixelIndex,
bool bBit0,
bool bBit1)
408 if (!bBit0 && !bBit1)
415 else if (!bBit0 && bBit1)
421 else if (bBit0 && !bBit1)
438 static void DoVITCBitPair (uint8_t *pLine, uint32_t& pixelIndex,
bool bPrevBit,
bool bBit0,
bool bBit1)
469 uint32_t pixelIndex = 0;
472 bool bPrevBit =
false;
476 for (i = 0; i < 26; i++)
484 uint8_t tcData, bgData;
487 uint8_t data = (bgData << 4) + tcData;
496 for (bitPair = 0; bitPair < 4; bitPair++)
498 bBit0 = (data & 0x01) > 0;
499 bBit1 = (data & 0x02) > 0;
529 for (i = 0; i < 4; i++)
531 bBit0 = (CRC & 0x80) > 0;
532 bBit1 = (CRC & 0x40) > 0;
544 const uint32_t remainingPixels (
GetDC() > pixelIndex ?
GetDC() - pixelIndex : 0);
546 for (i = 0; i < (uint32_t)remainingPixels; i++)
554 #else // use original NTV2 VITC algorithm 558 static void DoVITCPixel (uint8_t *pLine, uint32_t pixelNum,
float level)
565 pLine[pixelNum] = luma;
570 static void DoNormalTransition (uint8_t *pLine, uint32_t& pixelIndex,
bool bBit0,
bool bBit1)
572 if (!bBit0 && !bBit1)
581 else if (!bBit0 && bBit1)
590 else if (bBit0 && !bBit1)
613 static void DoHalfTransition (uint8_t *pLine, uint32_t& pixelIndex,
bool bBit0,
bool bBit1)
615 if (!bBit0 && !bBit1)
623 else if (!bBit0 && bBit1)
631 else if (bBit0 && !bBit1)
651 static void DoVITCBitPair (uint8_t *pLine, uint32_t& pixelIndex,
bool bPrevBit,
bool bBit0,
bool bBit1,
bool bDropBit)
659 level = (bBit0 ? (float)1.0 : (
float)0.0);
668 level = (bBit1 ? (float)1.0 : (
float)0.0);
682 uint32_t pixelIndex = 0;
686 bool bPrevBit =
false;
687 bool bDropBit =
false;
691 for (i = 0; i < 24; i++)
699 uint8_t tcData, bgData;
702 uint8_t data = (bgData << 4) + tcData;
711 for (bitPair = 0; bitPair < 4; bitPair++)
713 bBit0 = (data & 0x01) > 0;
714 bBit1 = (data & 0x02) > 0;
717 bDropBit = (group % 2 && bitPair == 3);
719 DoVITCBitPair(pLine, pixelIndex, bPrevBit, bBit0, bBit1, bDropBit);
747 for (i = 0; i < 4; i++)
749 bBit0 = (CRC & 0x80) > 0;
750 bBit1 = (CRC & 0x40) > 0;
752 DoVITCBitPair(pLine, pixelIndex, bPrevBit, bBit0, bBit1, bDropBit);
763 int32_t remainingPixels = m_DC - pixelIndex;
765 if (remainingPixels > 0)
767 for (i = 0; i < (uint32_t)remainingPixels; i++)
774 #endif // !USE_SMPTE_266M virtual const uint8_t * GetPayloadData(void) const
virtual std::ostream & Print(std::ostream &inOutStream, const bool inDetailed=false) const
Streams a human-readable representation of me to the given output stream.
SMPTE 12-M Vertical Interval Timecode (aka "VITC")
const uint8_t VITC_YUV8_HI
virtual AJAStatus GetBinaryGroupHexValue(uint8_t digitNum, uint8_t &hexValue, uint8_t mask=0x0f) const
static std::string VITCTypeToString(const AJAAncillaryData_Timecode_VITC_Type inType)
AJAAncDataType m_ancType
One of a known set of ancillary data types (or "Custom" if not identified)
#define AJA_FAILURE(_status_)
AJAAncDataType
Identifies the ancillary data types that are known to this module.
AJAStatus EncodeLine(uint8_t *pOutLine) const
The ancillary data is in the form of a digitized waveform (e.g. CEA-608 captions, VITC...
uint8_t m_checksum
My 8-bit checksum: DID + SID + DC + payload (w/o parity) [note: NOT the same as the 9-bit checksum in...
AJAAncillaryData_Timecode & operator=(const AJAAncillaryData_Timecode &inRHS)
Assignment operator – replaces my contents with the right-hand-side value.
AJAAncillaryData_Timecode_VITC_Type m_vitcType
The "type" of VITC received or to be transmitted.
ByteVector m_payload
My payload data (DC = size)
AJAAncDataCoding m_coding
Analog or digital data.
virtual uint16_t GetLocationLineNumber(void) const
virtual AJAStatus SetLocationLineNumber(const uint16_t inLineNum)
Sets my ancillary data "location" frame line number.
AJAAncillaryData_Timecode_VITC_Type
const uint32_t VITC_DECODE_START_WINDOW
This is the VITC-specific subclass of the AJAAncillaryData_Timecode class.
virtual AJAAncillaryData_Timecode_VITC & operator=(const AJAAncillaryData_Timecode_VITC &inRHS)
Assignment operator – replaces my contents with the right-hand-side value.
Includes data that is valid, but we don't recognize.
static void DoHalfTransition(uint8_t *pLine, uint32_t &pixelIndex, bool bBit0, bool bBit1)
virtual AJAStatus GeneratePayloadData(void)
Generate the payload data from the "local" ancillary data.
virtual AJAStatus GetTimeHexValue(uint8_t inDigitNum, uint8_t &outHexValue, uint8_t inMask=0x0f) const
Answers with my current raw "time" hex values.
static bool getVITCLevel(uint32_t pixelNum, const uint8_t *pLine)
const uint8_t AJAAncillaryData_VITC_DID
static void DoVITCPixel(uint8_t *pOutLine, const uint32_t inPixelNum, const uint8_t inLevel)
bool DecodeLine(const uint8_t *pInLine)
virtual uint8_t Calculate8BitChecksum(void) const
Generates an 8-bit checksum from the DID + SID + DC + payload data.
virtual void Clear(void)
Frees my allocated memory, if any, and resets my members to their default values. ...
This is the base class for the AJAAncillaryData_Timecode_ATC and AJAAncillaryData_Timecode_VITC class...
virtual AJAStatus SetVITCDataType(const AJAAncillaryData_Timecode_VITC_Type inType)
Sets my VITC data type.
static AJAAncDataType RecognizeThisAncillaryData(const AJAAncillaryData *pInAncData)
const uint32_t VITC_DECODE_END_WINDOW
Declares the AJAAncillaryData_Timecode_VITC class.
const uint32_t AJAAncillaryData_VITC_PayloadSize
uint8_t m_SID
Official SMPTE secondary ID (or DBN - w/o parity)
virtual void Clear(void)
Frees my allocated memory, if any, and resets my members to their default values. ...
virtual AJAAncDataCoding GetDataCoding(void) const
uint8_t m_DID
Official SMPTE ancillary packet ID (w/o parity)
const std::string & AJAAncDataCodingToString(const AJAAncDataCoding inValue, const bool inCompact=true)
AJAAncillaryData_Timecode_VITC()
virtual uint32_t GetDC(void) const
const uint8_t VITC_Y_CLIP
virtual AJAStatus ParsePayloadData(void)
Parses out (interprets) the "local" ancillary data from my payload data.
const uint8_t AJAAncillaryData_VITC_SID
virtual std::string IDAsString(void) const
I am the principal class that stores a single SMPTE-291 SDI ancillary data packet OR the digitized co...
bool m_rcvDataValid
This is set true (or not) by ParsePayloadData()
static void DoNormalTransition(uint8_t *pLine, uint32_t &pixelIndex, bool bBit0, bool bBit1)
static void addToCRC(const bool inBit, uint8_t &inOutCRC)
virtual AJAStatus SetTimeHexValue(const uint8_t inDigitNum, const uint8_t inHexValue, const uint8_t inMask=0x0f)
Sets my raw "time" hex values.
AJAStatus AllocDataMemory(const uint32_t inNumBytes)
static void DoVITCBitPair(uint8_t *pLine, uint32_t &pixelIndex, bool bPrevBit, bool bBit0, bool bBit1)
virtual std::ostream & Print(std::ostream &inOutStream, const bool inDetailed=false) const
Streams a human-readable representation of me to the given output stream.
virtual AJAStatus SetBinaryGroupHexValue(uint8_t digitNum, uint8_t hexValue, uint8_t mask=0x0f)
Sets my raw "Binary Group" hex values.
const uint8_t VITC_YUV8_LO