From fc080f81ca6921da0091e1bdfd33ba0972025f52 Mon Sep 17 00:00:00 2001 From: Erik Zandvliet Date: Mon, 17 Nov 2014 14:45:07 +0100 Subject: [PATCH] Fixed CRC calculation for TS Packets, in particular the PAT --- lib/checksum.h | 8 ++++---- lib/ts_packet.cpp | 18 +++++++++--------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/checksum.h b/lib/checksum.h index 5593627c..d2aeba6d 100644 --- a/lib/checksum.h +++ b/lib/checksum.h @@ -219,10 +219,10 @@ namespace checksum { 0x6D66B4BCU, 0xDA7B75B8U, 0x035D36B5U, 0xB440F7B1U }; - while (len > 0) { - crc = table[*data ^ ((crc >> 24) & 0xff)] ^ (crc << 8); - data++; - len--; + const char * tmpData = data; + const char * end = tmpData + len; + while(tmpData < end){ + crc = table[((unsigned char) crc) ^ *tmpData++] ^ (crc >> 8); } return crc; } diff --git a/lib/ts_packet.cpp b/lib/ts_packet.cpp index 3a6ff8b2..28ef9696 100644 --- a/lib/ts_packet.cpp +++ b/lib/ts_packet.cpp @@ -919,20 +919,20 @@ namespace TS { return ((int)(strBuf[loc]) << 24) | ((int)(strBuf[loc + 1]) << 16) | ((int)(strBuf[loc + 2]) << 8) | strBuf[loc + 3]; } - /// \todo checksum is calculated wrong, but the stream plays. Fix checksum when deadlines are less tight. void ProgramMappingTable::calcCRC() { - unsigned int loc = 4 + (AdaptationField() > 1 ? AdaptationFieldLen() + 1 : 0) + getOffset() + 13 + getProgramInfoLength() + (getProgramCount() * 5); + unsigned int loc = 4 + (AdaptationField() > 1 ? AdaptationFieldLen() + 1 : 0) + getOffset() + getSectionLength(); unsigned int newVal;//this will hold the CRC32 value; - unsigned int pidLoc = 4 + (AdaptationField() > 1 ? AdaptationFieldLen() + 1 : 0) + getOffset() + 9;;//location of PCRPID - newVal = checksum::crc32LE(0, strBuf.c_str() + pidLoc, loc - pidLoc);//calculating checksum over all the fields from table ID to the last stream element + unsigned int pidLoc = 4 + (AdaptationField() > 1 ? AdaptationFieldLen() + 1 : 0) + getOffset() + 1;//location of PCRPID + INFO_MSG("Calculating checksum from offset %d, over %d bytes", pidLoc, loc - pidLoc); + newVal = checksum::crc32(-1, strBuf.c_str() + pidLoc, loc - pidLoc);//calculating checksum over all the fields from table ID to the last stream element if (strBuf.size() < 188) { strBuf.resize(188); } - strBuf[loc] = (newVal >> 24) & 0xFF; - strBuf[loc + 1] = (newVal >> 16) & 0xFF; - strBuf[loc + 2] = (newVal >> 8) & 0xFF; - strBuf[loc + 3] = newVal & 0xFF; - memset((void*)(strBuf.c_str() + loc + 4), 0xFF, 180 - loc); + strBuf[loc + 3] = (newVal >> 24) & 0xFF; + strBuf[loc + 2] = (newVal >> 16) & 0xFF; + strBuf[loc + 1] = (newVal >> 8) & 0xFF; + strBuf[loc] = newVal & 0xFF; + memset((void*)(strBuf.c_str() + loc + 4), 0xFF, 184 - loc); } ///Print all PMT values in a human readable format