📄 dvb_si.c
字号:
u8 u16program_number = 0, u8PatCount = 0;
u16 u16descriptor_length = 0;
u8 u8FoundMeetWithPAT = 0xff;
if (pu8Section == NULL || pstSrvItem == NULL)
return;
u8num_channels_in_section = *(pu8Section+9);
pu8channel_info = pu8Section + 10;
SI_DBG(("u8num_channels_in_section[%d]\n", u8num_channels_in_section));
for (u8channel_idx = 0; u8channel_idx < u8num_channels_in_section; u8channel_idx ++)
{
if (u8FoundMeetWithPAT == 0)
{
/* mean not find the channel */
pu8channel_info += (14 + 3 + 9);
u16descriptor_length = (u16)((*pu8channel_info+4) & 0x03 << 8) + (*(pu8channel_info+5));
pu8channel_info += 6;
pu8channel_info += (u16descriptor_length);
}
u16program_number = PU8TOU16(pu8channel_info + 24);
/* reset */
u8FoundMeetWithPAT = 0;
for (u8PatCount = 0; u8PatCount < u8NumOfPatItem; u8PatCount ++)
{
if ((pstPATItem + u8PatCount)->u16ProgramNumber == u16program_number)
{
/* found the meet with PAT */
u8FoundMeetWithPAT = 1;
(pstSrvItem + u8PatCount)->acServiceName[0] = 0x11;
memcpy (&((pstSrvItem + u8PatCount)->acServiceName[1]), pu8channel_info,
MAX_UTF16_SERVICE_NAME_LENGTH * 2);
pu8channel_info += 14;
(pstSrvItem + u8PatCount)->u32MajorCHNo =
(*(pu8channel_info) & 0x0f) << 6 | (*(pu8channel_info+1)>>2);
(pstSrvItem + u8PatCount)->u32MinorCHNo =
((*(pu8channel_info + 1) & 0x03) << 8) | (*(pu8channel_info + 2));
pu8channel_info += 3;
pu8channel_info += 9;
// SI_DBG(("ETM_Location[%d]\n", *(pu8channel_info) >> 6));
// SI_DBG(("access-control[%d]\n", ((*(pu8channel_info) >> 5) & 0x01)));
// SI_DBG(("hidden[%d]\n", ((*(pu8channel_info) >> 4) & 0x01)));
// SI_DBG(("hide_guide[%d]\n", ((*(pu8channel_info) >> 1) & 0x01)));
(pstSrvItem + u8PatCount)->u32AccessCtrl = (*(pu8channel_info) >> 5) & 0x01;
(pstSrvItem + u8PatCount)->u32Hidden = (*(pu8channel_info) >> 4) & 0x01;
(pstSrvItem + u8PatCount)->u32HideGuide = (*(pu8channel_info) >> 1) & 0x01;
(pstSrvItem + u8PatCount)->u32ServiceType = *(pu8channel_info + 1) & 0x3f;
SI_DBG(("ETM_Location[%d]\n", *(pu8channel_info) >> 6));
SI_DBG(("access-control[%d]\n", (pstSrvItem + u8PatCount)->u32AccessCtrl));
SI_DBG(("hidden[%d]\n", (pstSrvItem + u8PatCount)->u32Hidden));
SI_DBG(("hide_guide[%d]\n", (pstSrvItem + u8PatCount)->u32HideGuide));
/* service type */
SI_DBG(("servcie_type[%d]\n", *(pu8channel_info + 1) & 0x3f));
#if defined(CHECK_SERVICE_TYPE_BY_TVCT)
// copy service type
(pstSrvItem + u8PatCount)->u16TypeEX = *(pu8channel_info + 1) & 0x3f;
#endif
/* source id */
(pstSrvItem + u8PatCount)->u16SourceID = PU8TOU16(pu8channel_info+2);
SI_DBG(("source_id[%d]\n", PU8TOU16(pu8channel_info+2)));
/* descritor_length */
u16descriptor_length = (u16)((*pu8channel_info+4) & 0x03 << 8) + (*(pu8channel_info+5));
SI_DBG(("descriptor_length[%d]\n", u16descriptor_length));
pu8channel_info += 6;
pu8channel_info += (u16descriptor_length);
#ifdef CHECK_SERVICE_EXIST_BY_TVCT
(pstSrvItem + u8PatCount)->u16ServiceId = u16program_number;
#endif
}
}
}
return;
}
#else
void parser_sdt( u8* pu8Section )
{
u8 u8SrvLength;
u8* pu8SrvName;
u8* pu8Descriptor;
u16 u16ServiceID, u16TotlaDescriptorLength;
u8* pu8SDTLoop;
u8 u8SdtCount;
u16 u16TPIDofSDT = 0xffff;
//#ifdef ENABLE_LCN_SUPPORT
u16 u16TransportStreamID;
u16 u16OriginalNetworkID;
//#endif
if (pu8Section==NULL||pstSrvItem==NULL)
return;
u16TPIDofSDT = (u16)((((*(pu8Section+3))<<8)&0xFF00)|((*(pu8Section+4))&0x00FF));
if (u16TPID != u16TPIDofSDT)
{
/* not the matched SDT, because the transport stream id is different */
return;
}
u16OrgNID=(u16)((((*(pu8Section+8))<<8)&0xFF00)|((*(pu8Section+9))&0x00FF));
u16TPID = u16TPIDofSDT;
//SI_DBG(("parse SDT u16OrgNID[0x%x] u16TPID[0x%x]\n", u16OrgNID, u16TPID));
//#ifdef ENABLE_LCN_SUPPORT
u16TransportStreamID=(u16)((((*(pu8Section+3))<<8)&0xFF00)|((*(pu8Section+4))&0x00FF));
u16OriginalNetworkID=(u16)((((*(pu8Section+8))<<8)&0xFF00)|((*(pu8Section+9))&0x00FF));
//#endif
// first loop
pu8SDTLoop=DVB_ParserFindFirstLoop(pu8Section, EN_SDT);
// get each loop of service id
while (pu8SDTLoop!=NULL)
{
u16ServiceID=PU8TOU16(pu8SDTLoop);
u16TotlaDescriptorLength=PU8TOU16(pu8SDTLoop+3)&0x0fff;
pu8Descriptor=pu8SDTLoop+5;
// find coressponded srvitem to update
for (u8SdtCount=0; u8SdtCount<u8NumOfPatItem; u8SdtCount++)
{
if ((pstPATItem+u8SdtCount)->u16ProgramNumber==u16ServiceID)
{
// set ID
(pstSrvItem+u8SdtCount)->u16TSID=u16TransportStreamID;
(pstSrvItem+u8SdtCount)->u16ONID=u16OriginalNetworkID;
//SI_DBG(("%d=%d\n",u8SdtCount,(pstSrvItem+u8SdtCount)->u8Type));
// free CA mode
#ifdef CHECK_SCRAMBLE_BY_BOTH
//wilson 2006.10.12 for in both mode not decide scrambled by SDT(only by PMT),and free is decide only by SDT
/*
if ( ((pu8SDTLoop [3]>>4)&0x01)==0 && (pstSrvItem+u8SdtCount)->u8Type == FREE_TYPE )
{
SI_DBG(("Free srv, "));
(pstSrvItem+u8SdtCount)->u8Type=FREE_TYPE; // default is scramble
}
else
{
(pstSrvItem+u8SdtCount)->u8Type = SCRAMBLE_TYPE;
SI_DBG(("Scramble, "));
}
*/
if ( ((pu8SDTLoop [3]>>4)&0x01)==0 )
{
(pstSrvItem+u8SdtCount)->u8Type=FREE_TYPE; // default is scramble
}
#endif
#if defined(CHECK_SCRAMBLE_BY_SDT)
(pstSrvItem+u8SdtCount)->u8Type=( (pu8SDTLoop [3]>>4)&0x01 )<<6;
#endif
// get service name, and type
pu8Descriptor=DVB_ParserFindTag(pu8Descriptor, TAG_SeD, u16TotlaDescriptorLength);
if (pu8Descriptor!=NULL)
{
#if defined(CHECK_SERVICETYPE_BY_SDT)
// copy service type
(pstSrvItem+u8SdtCount)->u16TypeEX=(u16)pu8Descriptor [2];
#endif
#ifdef D_UI
(pstSrvItem+u8SdtCount)->u16TypeEX=(u8)pu8Descriptor [2];
#endif
u8SrvLength=pu8Descriptor[3];
pu8SrvName=&pu8Descriptor[4];
switch (DVB_DBGetSystemType())
{
#ifdef DVB_SYSTEM_C
case EN_SYSTEM_TYPE_DVBC:
copy_text_from_si(m_stNetItem.netCable.acProviderName, pu8SrvName, MAX_PROVIDER_NAME_LENGTH,
u8SrvLength);
break;
#else
case EN_SYSTEM_TYPE_DVBT:
copy_text_from_si(m_stNetItem.netTerre.acProviderName, pu8SrvName, MAX_PROVIDER_NAME_LENGTH,
u8SrvLength);
break;
#endif
#if defined(DVB_SYSTEM_DTMB)
case EN_SYSTEM_TYPE_DTMB:
copy_text_from_si(m_stNetItem.netDtmb.acProviderName, pu8SrvName, MAX_PROVIDER_NAME_LENGTH,
u8SrvLength);
break;
#endif
case EN_SYSTEM_TYPE_DVBS:
default:
break;
}
u8SrvLength=pu8Descriptor [4+pu8Descriptor [3]];
if (u8SrvLength>=MAX_SERVICE_NAME_LENGTH)
u8SrvLength=MAX_SERVICE_NAME_LENGTH-1;
pu8SrvName=pu8Descriptor+(4+pu8Descriptor [3]+1);
#ifdef CHECK_SERVICE_BY_TRUST_SDT
(pstSrvItem+u8SdtCount)->u16ServiceId=u16ServiceID;
#endif
copy_text_from_si((pstSrvItem+u8SdtCount)->acServiceName, pu8SrvName, MAX_SERVICE_NAME_LENGTH,
u8SrvLength);
SI_DBG(("SID: %04X, Name: %s, Len: %d\n", u16ServiceID, (pstSrvItem+u8SdtCount)->acServiceName,
(int)u8SrvLength));
}
else
{
(pstSrvItem+u8SdtCount)->acServiceName [0]='\0';
}
#ifdef LCN_COUNTRY_CHECK_DISABLE
// printf("[%02d]type[%d], name[%s]\n",u8SdtCount,
// (pstSrvItem+u8SdtCount)->u16TypeEX, (pstSrvItem+u8SdtCount)->acServiceName);
#else
//SI_DBG(("[%d] ServiceID[0x%x] name[%s]\n",u8SdtCount,
// (pstSrvItem+u8SdtCount)->u16ServiceId, (pstSrvItem+u8SdtCount)->acServiceName));
#endif
}
//pstPATItem++;
}
pu8SDTLoop=DVB_ParserFindNextLoop(pu8Section, pu8SDTLoop, EN_SDT);
}
}
#endif /* end #ifndef ATSC_SYSTEM */
/*******************************************************************************************/
#ifdef ENABLE_LCN_SUPPORT
static void clear_lcn_list(void)
{
ST_LCNItem *pstLCNTmp = NULL;
while(m_pstLCNList)
{
pstLCNTmp = m_pstLCNList->pNext;
DVB_MemoryFree(m_pstLCNList);
m_pstLCNList->pNext = NULL;
m_pstLCNList = pstLCNTmp;
}
}
/*******************************************************************************************/
bool8 DVB_SI_GetLCNStatus( void )
{
if (enLCN_Mode != LCN_NULL_MODE)
{
return TRUE;
}
return FALSE;
}
/*******************************************************************************************/
void DVB_SI_SetLCNMode( EN_LCN_MODE enMode )
{
enLCN_Mode = enMode;
switch(enMode)
{
case GERMANY_MAPPING_MODE:
break;
case LCN_NORDIG_MODE:
u16LCNMask = NORDIG_LCN_MASK;
break;
case LCN_AUSTRALIA_MODE:
default:
u16LCNMask = AUSTRALIA_LCN_MASK;
break;
}
}
/*******************************************************************************************/
EN_LCN_MODE DVB_SI_GetLCNMode( void )
{
return enLCN_Mode;
}
/*******************************************************************************************/
u16 DVB_SI_GetLCNFreeNum( EN_SERVICE_TYPE tvRadioMode )
{
u16 i;
for(i = 0; i < DVB_ServiceGetTotal(tvRadioMode); i++)
{
if(DVB_GetDbIdxByLCNs(tvRadioMode, i, NULL) == 0xFFFF)
{
return i;
}
}
SI_DBG(( "[LCN] Not enough free LCN number can be get!\n"));
return 0;
}
/*******************************************************************************************/
bool8 DVB_SI_SetLCNNumber( DB_SrvDetail *pstService )
{
ST_LCNItem *pstLCNTmp = NULL;
if (enLCN_Mode == GERMANY_MAPPING_MODE)
{
u16 u16CheckCount;
for(u16CheckCount = 0; u16CheckCount < MAX_GERMANY_SERVICE_ID; u16CheckCount++)
{
if(u16GermanySrvMap[u16CheckCount] != pstService->u16ServiceId)
{
continue;
}
pstService->b1VisibleService = TRUE;
pstService->b1LCNEnable = TRUE;
pstService->u16LCN = u16CheckCount+1;
return TRUE;
}
return FALSE;
}
for(pstLCNTmp = m_pstLCNList; pstLCNTmp; pstLCNTmp = pstLCNTmp->pNext)
{
if ((pstLCNTmp->u16ServiceID != pstService->u16ServiceId) ||
((pstLCNTmp->u16LCN & u16LCNMask) == 0))
{
pstService->bitLCNGet = FALSE;
continue;
}
pstService->b1VisibleService = (pstLCNTmp->u16LCN & LCN_VISIBLE_MASK) >> 15;
pstService->b1LCNEnable = TRUE;
pstService->u16LCN = pstLCNTmp->u16LCN & u16LCNMask;
pstService->bitLCNGet = TRUE;
return TRUE;
}
return FALSE;
}
/*******************************************************************************************/
#ifdef LCN_COUNTRY_CHECK_DISABLE
u16 DVB_SI_Get_MaxLCN_In_DB(EN_SERVICE_TYPE enServiceType)
{
DB_SrvDetail pstSrvItemInDB;
DB_SrvRel pstSrvRel;
u8 u8CurTotalSrv = DVB_ServiceGetTotal (enServiceType);
u8 u8CheckLoop;
u16 u16MaxLCN = 0;
for (u8CheckLoop = 0; u8CheckLoop < u8CurTotalSrv; u8CheckLoop++)
{
DVB_ServiceReadDetail(enServiceType, u8CheckLoop, &pstSrvItemInDB, &pstSrvRel);
if(pstSrvItemInDB.bitLCNGet == TRUE)
{
if(pstSrvItemInDB.bitCollison == FALSE)
{
// printf("type[%d]: lcn[%04d], name[%s]\n", enServiceType + 1, pstSrvItemInDB.u16LCN, pstSrvItemInDB.acServiceName);
if (pstSrvItemInDB.u16LCN > u16MaxLCN)
{
u16MaxLCN = pstSrvItemInDB.u16LCN;
}
}
else
{
// printf("type[%d]: clcn[%04d], name[%s]\n", enServiceType + 1, pstSrvItemInDB.u16LCN, pstSrvItemInDB.acServiceName);
}
}
else
{
// printf("type[%d]: nlcn[%04d], name[%s]\n", enServiceType + 1, pstSrvItemInDB.u16LCN, pstSrvItemInDB.acServiceName);
}
}
return u16MaxLCN;
}
void DVB_SI_CheckMaxLCN (u16 *pu16MaxVideoLCN, u16 *pu16MaxAudioLCN)
{
ST_LCNItem *pstLCNTmp = NULL;
u16 u16CurMaxVideoLCN = 0;
u16 u16CurMaxAudioLCN = 0;
u8 u8CurTotalSrv = 0;
u8 u8CheckLoop;
bool8 bIsFoundNewMaxVLCN = FALSE;
bool8 bIsFoundNewMaxALCN = FALSE;
u16CurMaxVideoLCN = DVB_SI_Get_MaxLCN_In_DB(EN_SERVICE_TYPE_TV);
u16CurMaxAudioLCN = DVB_SI_Get_MaxLCN_In_DB(EN_SERVICE_TYPE_RADIO);
if(GetLCNStartNumber(EN_SERVICE_TYPE_TV) > u16CurMaxVideoLCN)
{
u16CurMaxVideoLCN = GetLCNStartNumber(EN_SERVICE_TYPE_TV);
}
if(GetLCNStartNumber(EN_SERVICE_TYPE_RADIO) > u16CurMaxAudioLCN)
{
u16CurMaxAudioLCN = GetLCNStartNumber(EN_SERVICE_TYPE_RADIO);
}
u8CurTotalSrv = DVB_SI_GetTotalService();
// printf("xxx pre-scan max lcn in current service [start] xxx\n");
for (u8CheckLoop = 0; u8CheckLoop < u8CurTotalSrv; u8CheckLoop++)
{
for(pstLCNTmp = m_pstLCNList; pstLCNTmp; pstLCNTmp = pstLCNTmp->pNext)
{
if (pstLCNTmp->u16ServiceID == pstSrvItem[u8CheckLoop].u16ServiceId)
{
u16 u16NewLCN = pstLCNTmp->u16LCN & u16LCNMask;
switch (pstSrvItem [u8CheckLoop].u16TypeEX)
{
case 1: // TV
case 0x11: // MPEG-2 HD TV
case 0x16: // Advanced codec SD TV
case 0x17: // Advanced codec SD NVOD time-shift
case 0x18: // Advanced codec SD NVOD reference
case 0x19: // Advanced codec HD TV
case 0x1A: // Advanced codec HD NVOD time-shift
case 0x1B: // Advanced codec HD NVOD reference
if(u16NewLCN > u16CurMaxVideoLCN)
{
u16CurMaxVideoLCN = u16NewLCN;
bIsFoundNewMaxVLCN = TRUE;
// printf("type[1], mlcn[%04d], name[%s]\n", u16NewLCN, pstSrvItem[u8CheckLoop].acServiceName);
}
break;
case 2: // AUDIO
if(u16NewLCN > u16CurMaxAudioLCN)
{
u16CurMaxAudioLCN = u16NewLCN;
bIsFoundNewMaxALCN = TRUE;
// printf("type[2], mlcn[%04d], name[%s]\n", u16NewLCN, pstSrvItem[u8CheckLoop].acServiceName);
}
break;
default:
// printf("[%d]non support, name[%s]\n", pstSrvItem [u8CheckLoop].u16TypeEX, pstSrvItem[u8CheckLoop].acServiceName);
// printf("[%d]", pstSrvItem [u8CheckLoop].u16TypeEX);
break;
}
}
//else printf("not the same %d != %d\n", pstLCNTmp->u16ServiceID, pstSrvItem[u8CheckLoop].u16ServiceId);
}
}
if(bIsFoundNewMaxVLCN == TRUE)
{
u16CurMaxVideoLCN++;
}
if(bIsFoundNewMaxALCN == TRUE)
{
u16CurMaxAudioLCN++;
}
*pu16MaxVideoLCN = u16CurMaxVideoLCN;
*pu16MaxAudioLCN = u16CurMaxAudioLCN;
printf("[video]max lcn: %04d, [audio]max lcn: %04d\n", u16CurMaxVideoLCN, u16CurMaxAudioLCN);
// printf("xxx pre-scan max lcn in current service [stop] xxx\n\n");
}
#else
u16 DVB_SI_CheckMaxLCN (void)
{
ST_LCNItem *pstLCNTmp = NULL;
DB_SrvDetail pstSrvItemInDB;
DB_SrvRel pstSrvRel;
u16 u16CurMaxLCN = 0;
u8 u8CurTotalSrv = 0;
u8 u8CheckLoop;
u8CurTotalSrv = DVB_ServiceGetTotal (EN_SERVICE_TYPE_TV);
for (u8CheckLoop = 0; u8CheckLoop < u8CurTotalSrv; u8CheckLoop++)
{
DVB_ServiceReadDetail(EN_SERVICE_TYPE_TV, u8CheckLoop, &pstSrvItemInDB, &pstSrvRel);
if (pstSrvItemInDB.bitLCNGet == TRUE)
{
if (pstSrvItemInDB.u16LCN > u16CurMaxLCN)
{
u16CurMaxLCN = pstSrvItemInDB.u16LCN;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -