Skip to content

Commit

Permalink
Add code to check CRC
Browse files Browse the repository at this point in the history
When processing TLV /MMT stream, you can check CRC.
DumpTS file.mmts  --CID=1 --pid=0xF300 --output=e00301.hevc
Even If CID or pid is incorrect, DumpTS can check CRC.
  • Loading branch information
MMT-TLVassociation committed May 20, 2022
1 parent d73fd98 commit c884656
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 3 deletions.
30 changes: 30 additions & 0 deletions src/DumpMMT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ SOFTWARE.
#include "ESRepacker.h"
#include "PayloadBuf.h"
#include <chrono>
#include "crc.h"

extern std::map<std::string, std::string, CaseInsensitiveComparator> g_params;
extern int g_verbose_level;
Expand Down Expand Up @@ -1939,6 +1940,13 @@ int DumpMMTOneStream()

auto start_time = std::chrono::high_resolution_clock::now();

//added to process CRC
uint8_t* signaling_data_byte;
uint8_t table_id;
uint16_t data_length = 0;
uint64_t CRC_res;
uint32_t CRC_in_data;

if (g_params.find("input") == g_params.end())
return -1;

Expand Down Expand Up @@ -2416,6 +2424,28 @@ int DumpMMTOneStream()
}
else if (pHeaderCompressedIPPacket->MMTP_Packet->Payload_type == 0x2)
{

if (pHeaderCompressedIPPacket->MMTP_Packet->Packet_id >= 0x8000 && pHeaderCompressedIPPacket->MMTP_Packet->Packet_id <= 0x8004 && pHeaderCompressedIPPacket->MMTP_Packet->Packet_id != 0x8001) //Packet_id 0x8001 doesn't include CRC32
{

//check CRC
pHeaderCompressedIPPacket->MMTP_Packet->ptr_Messages->ProcessCRC();
if (pHeaderCompressedIPPacket->MMTP_Packet->ptr_Messages->table_id <=0xA6) //0xA6 is EMT
{
data_length = pHeaderCompressedIPPacket->MMTP_Packet->ptr_Messages->data_length;
signaling_data_byte = pHeaderCompressedIPPacket->MMTP_Packet->ptr_Messages->getCRC();
CRC_res = CalcCRC(CRC32_MPEG, signaling_data_byte, data_length - 4);//Last 4 bytes are CRC in data stream
//Convert Last 4 bytes (uint8) into uint32_t
CRC_in_data = signaling_data_byte[data_length - 4] * 256 * 256 * 256 + signaling_data_byte[data_length - 3] * 256 * 256 + signaling_data_byte[data_length - 2] * 256 + signaling_data_byte[data_length - 1];

if ((uint32_t)CRC_res != CRC_in_data)
{
fprintf(stdout, "\n" "CRC check result: False, Packet_sequence_number %x, CRC data %x, CRC %x", pHeaderCompressedIPPacket->MMTP_Packet->Packet_sequence_number, CRC_in_data, CRC_res);
}
///else { fprintf(stdout, "\n" "CRC OK"); }
}
}

if (pHeaderCompressedIPPacket->MMTP_Packet->Packet_id == 0x1) // Process CA message
{
// Check there is an existed CID there or not, if it does NOT exist, add one
Expand Down
88 changes: 88 additions & 0 deletions src/MMT.h
Original file line number Diff line number Diff line change
Expand Up @@ -3150,6 +3150,53 @@ namespace MMT
}
};

struct MessageCRC : public Message
{

MessageCRC(uint32_t cbPayload = 0) : Message(cbPayload) {
}
uint8_t table_id;
uint16_t data_length = 0;
uint8_t* section_field;

// Always assume the message information bitstream is complete
int Unpack(CBitstream& bs)
{
int iRet = Message::Unpack(bs);
if (iRet < 0)
return iRet;

uint64_t left_bits = 0;
bs.Tell(&left_bits);

if (left_bits < 24ULL)
return RET_CODE_BOX_TOO_SMALL;

section_field = new uint8_t[length];
bs.Peek(section_field, length);

table_id = bs.GetByte();
data_length = length;//added for CRC calculation. Note section_field includes CRC32 data

return RET_CODE_SUCCESS;
}

uint8_t* getCRC()
{
return section_field;
}

void deleteCRC()
{
delete section_field;
}

virtual void Print(FILE* fp = nullptr, int indent = 0)
{
Message::Print(fp, indent);
}
};

// MPEG Media Transport Protocol packet
struct MMTPPacket
{
Expand Down Expand Up @@ -3581,6 +3628,10 @@ namespace MMT
std::vector<uint8_t>
payload;

uint8_t* signaling_data_byte;
uint8_t table_id;
uint16_t data_length;

ControlMessages(MMTPPacket* pMMTPpkt, int nPayloadDataLen)
: fragmentation_indicator(0)
, reserved(0)
Expand Down Expand Up @@ -3679,6 +3730,43 @@ namespace MMT
return iRet;
}

void ProcessCRC(FILE* fp = nullptr, int indent = 0)
{
if (fragmentation_indicator == 0)
{
for (auto& v : messages)
{
auto& msg_payload = std::get<1>(v);
CBitstream msg_bs(&msg_payload[0], msg_payload.size() << 3);
uint16_t peek_msg_id = (uint16_t)msg_bs.PeekBits(16);
if (peek_msg_id == 0x8000 || 0x8002 || 0x8003 || 0x8004)// Packet_id, which includes CRC32
{
MessageCRC* ptr_M2Msg = new MessageCRC((uint32_t)msg_payload.size());
if (ptr_M2Msg->Unpack(msg_bs) >= 0)
{
table_id = ptr_M2Msg->table_id;
data_length = ptr_M2Msg->data_length;
signaling_data_byte = new uint8_t[(int)data_length];
signaling_data_byte = ptr_M2Msg->getCRC();
}

delete ptr_M2Msg;

}
}

}
}
uint8_t* getCRC()
{
return signaling_data_byte;
}

void deleteCRC()
{
delete signaling_data_byte;
}

void Print(FILE* fp = nullptr, int indent = 0)
{
FILE* out = fp ? fp : stdout;
Expand Down
4 changes: 2 additions & 2 deletions src/crc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -487,14 +487,14 @@ inline uint64_t _ReserveCRCBits(uint64_t u64Ret, uint8_t width)
return uRet;\
}\

uint64_t CalcCRC(CRC_TYPE type, const uint8_t* pBuf, size_t cbSize)
uint64_t CalcCRC(CRC_TYPE type, uint8_t* pBuf, size_t cbSize)
{
if (type < 0 || type >= CRC_MAX)
return UINT64_MAX;

_InitCRC(type);

const uint8_t* pEndBuf = pBuf + cbSize;
uint8_t* pEndBuf = pBuf + cbSize;
uint8_t crc_width = crc_props[type].width;
uint64_t* crc_lut = crc_props[type].CRCLookupTable;
bool bNeedReservedBit = crc_props[type].Reversed;
Expand Down
2 changes: 1 addition & 1 deletion src/crc.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ typedef uint32_t crc;
#endif
crc F_CRC_CalculaCheckSum(uint8_t const AF_Datos[], size_t VF_nBytes);

uint64_t CalcCRC(CRC_TYPE type, const uint8_t* pBuf, size_t cbSize);
uint64_t CalcCRC(CRC_TYPE type, uint8_t* pBuf, size_t cbSize);

CRC_HANDLE BeginCRC(CRC_TYPE type);
void ProcessCRC(CRC_HANDLE handle, const uint8_t* pBuf, size_t cbSize);
Expand Down

0 comments on commit c884656

Please sign in to comment.