📄 controldemux.cpp
字号:
/////////////////
//Author: Wenson Chen.
//Company: Innofidei.com
//Date: 2007/09/26-
//Licesence Notes:
//
/*++
Control Table(TS0) demuxer code
Copyright (C) 2007-2008 Innofidei, Inc.
Module Name: ControlDemux.cpp
History:
--*/
#include "Demux.h"
#include "string.h"
#include "stdio.h"
#ifndef _DEBUG
//#define printf(...) //
#endif
void CDemuxer::OnEmmPacket(LPBYTE data, size_t len, int CAS_ID) {}
void CDemuxer::ParseCMct()
{
for(int f=0;f<m_Cmct.nMfNum;f++)
{
int total = m_Cmct.tFrameDesc[f].nSubFrameNum;
for(int sub=0;sub<total;sub++)
{
CService service = {0};
service.mfId = m_Cmct.tFrameDesc[f].nMfId;
service.nSubFrame = sub;
service.serviceid = m_Cmct.tFrameDesc[f].tSubFramAndService[sub].wServiceId; //16 Service ID
service.serviceNameLen=0; //8 name length
service.serviceName[0]=0; //2-40Bytes name
service.demod = m_Cmct.tFrameDesc[f].demod;
service.freq = m_Cmct.nFreq; //freq
service.nts = m_Cmct.tFrameDesc[f].nSlotNum; //8 the count of timeslots
service.startTs = m_Cmct.tFrameDesc[f].nStartTs;
OnContinusServiceInfo(service);
}
}
}
void CDemuxer::ParseSMct()
{
for(int f=0;f<m_Smct.nMfNum;f++)
{
int total = m_Smct.tFrameDesc[f].nSubFrameNum;
for(int sub=0;sub<total;sub++)
{
CService service = {0};
service.mfId = m_Cmct.tFrameDesc[f].nMfId;
service.nSubFrame = sub;
service.serviceid = m_Smct.tFrameDesc[f].tSubFramAndService[sub].wServiceId; //16 Service ID
service.serviceNameLen=0;//8 name length
service.serviceName[0]=0;//2-40Bytes name
service.demod = m_Smct.tFrameDesc[f].demod;
service.freq = m_Smct.nFreq; //freq
service.nts = m_Smct.tFrameDesc[f].nSlotNum; //8 the count of timeslots
service.startTs = m_Smct.tFrameDesc[f].nStartTs;
OnShortServiceInfo(service);
}
}
}
void CDemuxer::OnShortServiceInfo(CService& rService){}
void CDemuxer::OnContinusServiceInfo(CService& rService){}
DWORD CNIT::Parse(LPBYTE lpIn, DWORD dwNitLen)
{
BYTE nTemp;
WORD wTemp;
unsigned i=0;
if(false == CheckCRC32(lpIn, dwNitLen-4))
return DEMUX_CRC_ERROR;
nTableSn = STEP1(lpIn);
nTemp = STEP1(lpIn);
nNitUpdateSn = nTemp >> 4;
MJDDate = STEP2(lpIn);
STEPTIME(lpIn, nHour, nMinute, nSecond);
CountryCode[0] = STEP1(lpIn);
CountryCode[1] = STEP1(lpIn);
CountryCode[2] = STEP1(lpIn);
CountryCode[3] = 0;
wTemp = STEP2(lpIn);
nNetLevel = wTemp >> 12; //bit12-15
wZoneNetNum = (wTemp & 0xFFF); //bit0-11
NetNameLen = STEP1(lpIn);
NetNameLen = NetNameLen > 38 ? 38 : NetNameLen;
STEPS((LPBYTE)NetName, lpIn, NetNameLen);
NetName[NetNameLen] = 0;
nFreq = STEP1(lpIn);
dwCenterFreq = STEP4(lpIn);
nTemp = STEP1(lpIn);
nBandWidth = nTemp >> 4;
nOtherFreqDotNum= nTemp & 0xF;
for(i =0; i < nOtherFreqDotNum; i++)
{
tOtherFreqDot[i].nFreq = STEP1(lpIn);
tOtherFreqDot[i].dwFreq = STEP4(lpIn);
nTemp = STEP1(lpIn);
tOtherFreqDot[i].nBandWidth = (nTemp >> 4);
}
nTemp = STEP1(lpIn);
nNearNetNum = (nTemp >> 4);
for(i = 0; i < nNearNetNum; i++)
{
wTemp = STEP2(lpIn);
tNeighborZoneInfo[i].nNetLevel = wTemp >> 12;
tNeighborZoneInfo[i].wNetZoneSn = wTemp & 0xFFF;
tNeighborZoneInfo[i].nBandWidth = STEP1(lpIn);
tNeighborZoneInfo[i].dwFreq = STEP4(lpIn);
nTemp = STEP1(lpIn);
tNeighborZoneInfo[i].nFreq = nTemp >> 4;
}
return DEMUX_NO_ERROR;
}
DWORD CMCT::Parse(LPBYTE lpIn, DWORD dwMctLen)
{
if(false == CheckCRC32(lpIn, dwMctLen-4))
return DEMUX_CRC_ERROR;
nTableSn = STEP1(lpIn);/* table id */
nFreq = STEP1(lpIn);/* freq */
WORD wTemp = STEP2(lpIn);
nMctUpdateSn = (wTemp >> 12);
nMfNum = (wTemp & 0x3F);
for(unsigned i = 0; i < nMfNum; i++)
{
BYTE nTemp = STEP1(lpIn);
wTemp = STEP2(lpIn);
tFrameDesc[i].nMfId = nTemp >> 2;
BYTE nRsCodeSpeed = nTemp & 3;
BYTE nInterlace = wTemp >> 14;
BYTE nLdpcCodeSpeed = (wTemp >> 12) & 3;
BYTE nModulate = (wTemp >> 10) & 3;
tFrameDesc[i].demod = MakeDemod(nRsCodeSpeed, nInterlace, nLdpcCodeSpeed, nModulate); // RS bit rate 2
tFrameDesc[i].nScramble = (wTemp >> 6) & 7; //
tFrameDesc[i].nSlotNum = wTemp & 0x3f; //
tFrameDesc[i].nStartTs = GET1(lpIn) >> 2;
lpIn +=tFrameDesc[i].nSlotNum;
nTemp = STEP1(lpIn);
tFrameDesc[i].nSubFrameNum = nTemp & 0xF;
for(unsigned j=0; j < tFrameDesc[i].nSubFrameNum; j++)
{
nTemp = STEP1(lpIn);
tFrameDesc[i].tSubFramAndService[j].nSubFrame = nTemp >> 4; //
tFrameDesc[i].tSubFramAndService[j].wServiceId = STEP2(lpIn); //
}
}
return DEMUX_NO_ERROR;
}
#ifdef USE_SCT
DWORD CSCT::Parse(LPBYTE lpIn, DWORD dwSctLen)
{
if(false == CheckCRC32(lpIn, dwSctLen-4))
return DEMUX_CRC_ERROR;
/* 获取table id */
nTableSn = STEP1(lpIn);
/* 段长度 */
wSegLen = STEP2(lpIn);
/* 段号 */
nSegSn = STEP1(lpIn);
/* 段数量 */
nSegNum = STEP1(lpIn);
/* 业务配置表更新序号+保留 */
BYTE nTemp = STEP1(lpIn);
nSctUpdateSn = nTemp >> 4;
/* 业务数量 */
wServiceNum = STEP2(lpIn);
for(int i = 0; i < wServiceNum; i++)
{
if(i<512)
{
pServiceDesc[i].wServiceSign= STEP2(lpIn);/* 业务标识 */
pServiceDesc[i].nFreq = STEP1(lpIn);/* 业务频点 */
}
else
{
STEP3(lpIn);
}
}
return DEMUX_NO_ERROR;
}
#endif
DWORD CCA::Parse(LPBYTE lpIn, DWORD dwLen)
{
if(false == CheckCRC32(lpIn, dwLen-4))
return DEMUX_CRC_ERROR;
tableId = STEP1(lpIn);
Section_Length = STEP2(lpIn);
Update_Number = (BYTE) (STEP3(lpIn) & 0x0f);
Section_Number = STEP1(lpIn);
Section_Quantity = STEP1(lpIn);
for (int i = 0; i < Section_Quantity; i++ )
{
section[i].CA_System_ID = STEP2(lpIn);
section[i].Service_ID = STEP2(lpIn);
section[i].EMM_Data_Type = STEP1(lpIn);
section[i].ECM_Data_Type = STEP1(lpIn);
section[i].ECM_Transport_Type =(BYTE) (STEP4(lpIn)>>30);
}
return DEMUX_NO_ERROR;
}
int CESG::Parse(LPBYTE lpIn, WORD dwLen)
{
unsigned i;
if(false == CheckCRC32(lpIn, dwLen-4))
return DEMUX_CRC_ERROR;
nTableSn = STEP1(lpIn);
WORD wTemp = STEP2(lpIn);
nUpdateSn = wTemp >> 12; //
nSegLen = wTemp & 0xfff; //
BYTE nTemp = STEP1(lpIn);
nSegSn = nTemp >> 4; //
nSegNumber = nTemp & 0xf; //
wTemp = STEP2(lpIn);
nNetworkLevel= wTemp>>12; //
nNetworkID = wTemp & 0xfff; //
nTemp = STEP1(lpIn);
nTimeDis = nTemp & 0x3f; //
/*
0000 GB2312
0001 GB18030
0010 GB13000.1
0011 UTF-8
*/
nTemp = STEP1(lpIn);
nCharType = nTemp >> 4; //
nEsgServiceCount = nTemp & 0xf; //
for(i=0;i<nEsgServiceCount;i++)
{
nTemp = STEP1(lpIn);
tEsgService[i].nEsgIndexId = nTemp & 0xf; //
tEsgService[i].nEsgId = STEP2(lpIn); //16
}
nTemp = STEP1(lpIn);
nDataTypeCount= nTemp & 0xf; //
for(i=0;i<nDataTypeCount;i++)
{
nTemp = STEP1(lpIn);
tEsgDataType[i].nDataType = (nTemp >> 4) & 0x0F; //4
tEsgDataType[i].nDataCount= STEP1(lpIn);//8
for(unsigned j=0;j<tEsgDataType[i].nDataCount;j++) //
{
tEsgDataType[i].tDataDesc[j].nDataTypeId = STEP1(lpIn); //8bits
nTemp = STEP1(lpIn);
tEsgDataType[i].tDataDesc[j].nDataVersion = nTemp >> 4; //4bits
tEsgDataType[i].tDataDesc[j].ESGServiceIndexId = nTemp & 0xf; //4bits
}
}
return DEMUX_NO_ERROR;
}
//A EB Fragment is the EB message in "One Second TS0",
//There may be long message whcih is splitted into more than one fragment, transmitted in more than one second
int CEBFragment::Parse(LPBYTE lpIn, WORD dwLen)
{
if(false == CheckCRC32(lpIn, dwLen-4))
return DEMUX_CRC_ERROR;
nTableSn = STEP1(lpIn);
BYTE nTemp = STEP1(lpIn);
nConcurrentMsgCount = nTemp>>4;
nSquence = nTemp & 3; // Sequence Number
wLen = STEP2(lpIn); // The left length of this fragment
//////////////////////////////////////////////////////
nTemp = STEP1(lpIn);
mProtocolVer = nTemp>>4; // 4 bits
mProtocolLowestVer = nTemp&0xf; // 4 bits
WORD wTemp = STEP2(lpIn);
mNetLevel = wTemp >> 12; // 4 bits
mNetID = wTemp & 0x0FFF; // 12 bits
mMsgID = STEP2(lpIn); // 16 bits, The message unique ID, The user will combine the message according to this ID
mSegSN = STEP1(lpIn); // 8 bits, 0~255
mLastSegSN = STEP1(lpIn); // 8 bits, 1-255
wDataLen = STEP2(lpIn) & 0x1FFF; //13 bits, (0-8191)
lpMessage = lpIn;
return 0;
}
int CEBContent::Parse(LPBYTE lpIn, WORD length)
{
int i=0;
LPBYTE lpEnd = lpIn + length;
BYTE nTemp = STEP1(lpIn);
tiggerFlag = nTemp >> 7; // 1 bits
msgType = nTemp & 0x7F; // 7 bits
if (tiggerFlag == 0)
{
nTemp = STEP1(lpIn);
msgLevel = nTemp >> 5; // 3 bits
charset = (nTemp >> 2) & 3; // 3 bits
// 40 bits
mjdDate = STEP2(lpIn);
STEPTIME(lpIn, nHour, nMinute, nSecond);
DWORD nTemp = STEP3(lpIn);
duration = nTemp>>4; // 20
langCount = BYTE(nTemp & 0x0F); // 4
for (i = 0; i < langCount; i++)
{
if(lpIn > lpEnd)
{
langCount = 0;
return -1;
}
mLangDesc[i].language[0] = STEP1(lpIn); // 24 bits
*(lpIn-1) = 0;
mLangDesc[i].language[1] = STEP1(lpIn);
mLangDesc[i].language[2] = STEP1(lpIn);
mLangDesc[i].language[3] = 0;
WORD wTemp = STEP2(lpIn);
bool publisherFlag = (wTemp >> 15) & 1; // 1
mLangDesc[i].refServiceFlag = (wTemp >> 14) & 1; // 1
mLangDesc[i].textLen = wTemp & 0x0FFF; // it is low 12 bit
mLangDesc[i].text = (char*)lpIn;
lpIn += mLangDesc[i].textLen;
if (publisherFlag == 1)
{
mLangDesc[i].publisherNameLen = STEP1(lpIn); // 8 bits
*(lpIn-1) = 0;
mLangDesc[i].publisherName = (char*)lpIn;
lpIn +=mLangDesc[i].publisherNameLen;
}
else
{
mLangDesc[i].publisherNameLen = 0; // 8 bits
}
if (mLangDesc[i].refServiceFlag == 1)
{
mLangDesc[i].refService = STEP2(lpIn); // 16
*(lpIn-2) = 0;
}
}
if(lpEnd - lpIn < 3)//At least 3 bytes for AuxInfo
{
auxInfoCount = 0;
return -1;
}
auxInfoCount = STEP1(lpIn) & 0x0F;
*(lpIn-1) = 0;// Add a EOS(End of String) into the "text"
for (i = 0; i < auxInfoCount; i++)
{
if(lpIn > lpEnd)
{
auxInfoCount = 0;
return -1;
}
mAuxDesc[i].auxDataType = STEP1(lpIn);
mAuxDesc[i].auxDataLen = STEP2(lpIn);
mAuxDesc[i].auxData = (char*)lpIn;
lpIn +=mAuxDesc[i].auxDataLen;
}
}
else
{
triggerMsgLevel = STEP1(lpIn) >> 5;
WORD wTemp = STEP2(lpIn);
netLevel = wTemp >> 12;
netID = wTemp & 0xfff;
nFreq = STEP1(lpIn);
dwCenterFreq = STEP4(lpIn);
nBandWidth = STEP1(lpIn) >> 4;
}
return 0;
}
bool CDemuxer::OnNitParsed(){return false;}
bool CDemuxer::OnCmctParsed(){return false;}
bool CDemuxer::OnSmctParsed(){return false;}
bool CDemuxer::OnEsgParsed(){return false;}
bool CDemuxer::OnCaParsed(){return false;}
bool CDemuxer::OnEbParsed(){return false;}
void CDemuxer::OnTS0Parsed(){}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -