⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dvb_si.c

📁 DVB软件,基于CT216软件的开发源程序.
💻 C
📖 第 1 页 / 共 5 页
字号:
	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 + -