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

📄 dvb_filt.c

📁 DVB软件,基于CT216软件的开发源程序.
💻 C
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************

        (C)Copyright Cheertek Inc. 2002-2005,
           K000, all right reserved.

        Product : STB Firmware

******************************************************************************/
/*!
\file
Section Filter API. This module provides the Section Filter control API.
*/
#include <string.h>
#include <stdio.h>

#include "ct_os.h"
//#include "u_ctrl.h"
//#include "drv_pidflt.h"
//#include "drv_proc2.h"
//#include "ct_secisr.h"
#include "ct_demux.h"
#include "ct_filter.h"
#include "ct_sys.h"

#include "task_cfg.h"
#include "av_cfg.h"

#include "dvb_type.h"
#include "dvb_filt.h"
#include "dvb_si.h"
#include "dvb_sys.h"
#include "dvb_msg.h"   // print message
#include "ct_type.h"

/*******************************************************************************************/
#define FILT_MSG(p)      printf p
//#define FILT_DBG(p)      printf p
#define FILT_DBG(p)
/*******************************************************************************************/
#define DEMUX_DISABLE					0
#define DEMUX_ENABLE					1
#define DEMUX_RESET				    	2
#define DEMUX_ENABLE_CONTINUOUS			3
/*******************************************************************************************/
#define DVB_SYSTIME_MILSEC_PER_TICK		1

#define DVB_FILTER_WAIT_10_MS			(10/CTOS_MS_PER_TICKS)   // 1 tick = 10 ms
#define DVB_FILTER_WAIT_100_MS			(100/CTOS_MS_PER_TICKS)   // 1 tick = 10 ms
#define DVB_FILTER_WAIT_1000_MS 		(1000/CTOS_MS_PER_TICKS)   // 1 tick = 10 ms
/*******************************************************************************************/
#define CTKDB_FILTER_MSG				1
/*******************************************************************************************/
#if (CTKDB_FILTER_MSG)
	#define DBM_FLT(__statement__)  __statement__
#else
	#define DBM_FLT(__statement__)
#endif
/*******************************************************************************************/
#define DVB_FILTER_MSG_DATA_NULL                            (0x00000000)
#define DVB_FILTER_MSG_DATA_INCREASE_AVAILABLE_NUM          (0x00000001)
#define DVB_FILTER_MSG_DATA_RING_BUFFER_OVERFLOW            (0x00000002)
/*******************************************************************************************/
static bool8 b8FilterInitialied = FALSE;
static CTOS_SEMAPHORE DVBFilterSemaphore;
static CTOS_SEMAPHORE DVBDPSemaphore;

// the default value for allocate section channel and filter
#define DEF_FILTER_DEPTH			CT_DEMUX_MAX_FILTER_DEPTH
#define DEF_MAX_FILTER_NUM			1
#ifdef ATSC_SYSTEM
	#define DEF_SECTION_BUFFER_SIZE		4096
#else
#define DEF_SECTION_BUFFER_SIZE		3072
#endif /* ATSC_SYSTEM */
#define DEF_EIT_SECTION_BUFFER_SIZE		8192

// the following is for task
CTOS_TASK	stDVBFilterTask,stDVBTimerTask;

u8	u8DVBFilterTaskStack [DVB_FILTER_TASK_STACK_SIZE];
u8	u8DVBTimerTaskStack [DVB_FILTER_TIMER_TASK_STACK_SIZE];
//u8  u8aPIDFltSecFltMap [MAX_PID_FILTER_NUMBER];
// record the information of filter (filter = channel)


ST_Filter_Channel_T astSectionFilter[MAX_FILTER_NUMBER];


#ifdef CT_INSTANT_DELAY
static EN_FILTER_NIM_DP enLiveTsDataPath    = EN_FILTER_NIM_DP_INTL;
#else
static EN_FILTER_NIM_DP enLiveTsDataPath    = EN_FILTER_NIM_DP_0;
#endif

static u8 dvb_filteropen (u32 u32UsrBfrSize);
static void dvb_filterset (u8 u8FID, u16 u16PID, DVB_SectionHeader* pstMask, DVB_SectionHeader* pstMatch,
	void (*sec_cb)(u8 u8FID, EN_FILTER_STATUS enStatus));
static void dvb_filtercleanbuffer(u8 u8FID);
static void dvb_filterstart (u8 u8FID, u16 u16TimeoutMilliSec, bool8 b8OneShot);
static bool8 dvb_filterchecktimeout (u8 u8FID);
static void dvb_filterclose (u8 u8FID);
static bool8 dvb_filtercheckavailablesection (u8 u8FID);
static bool8 dvb_filtergetsection (u8 u8FID, u8* pu8Section, u16 u16MaxLength);
static void dvb_filterrestart (u8 u8FID);
static void dvb_filterstop (u8 u8FID);
#define QUEUE_SIZE_DF		1024
#define QUEUE_SIZE_TIMER	1024
CTOS_QUEUE 			stDFQueue;
u32					u32DFQueueMsg[ QUEUE_SIZE_DF ],u32TimerQueueMsg[QUEUE_SIZE_TIMER];

void DVBFilter_Timer_Task (u32 argc, void *argv);

/*****************************************************************************/
bool8 dvb_filterchecktimeout (u8 u8FID)
{
	if (u8FID >= MAX_FILTER_NUMBER)
	{
		return (FALSE);
	}

	if (astSectionFilter[u8FID].u32TimerEnd == TIMEOUT_INFINITE)
	{
		FILT_DBG(( "{DVB_FilterCheckTimeOut} return TIMEOUT_INFINITE u8FID[0x%x]\n",u8FID));
		return (FALSE);
	}

	/* time after or before */
	if (DVB_TimerAfter (DVB_TimerGet(), astSectionFilter[u8FID].u32TimerEnd))
	{
		FILT_DBG(( "{DVB_FilterCheckTimeOut} DVB_TimerGet[0x%x] u32TimerEnd[0x%x]\n",
			DVB_TimerGet(), astSectionFilter[u8FID].u32TimerEnd));

		return (TRUE);
	}
	else
	{
		return (FALSE);
	}
}

/* this task will check the available status of every Filter by one by one
	call the call back func if the availabe is true */
void DVBFilter_Monitor_Task (u32 argc, void *argv)
{
	u8              u8FID           = 0;
	EN_CTOS_STATUS  enStatus; 
	MSG_PARAMETER	stDFRecvMsg;
	u32				u32DFRecvMsgLen = 0;
	u32             u32MsgData      = 0;
	
	void (*pfMonitorCallBack)(u8 u8FID, EN_FILTER_STATUS enStatus);
	
	while(1)
	{
		/* wait on semaphore or time out */
		u32MsgData = DVB_FILTER_MSG_DATA_NULL;
		enStatus = CT_OS_GetMsg(&stDFQueue, &stDFRecvMsg, &u32DFRecvMsgLen, CTOS_WAIT );//DVB_FILTER_WAIT_1000_MS
        
		if(enStatus != EN_CTOS_SUCCESS)
		{
			continue;
		}	
		u8FID       = stDFRecvMsg.u8Cmd;
        u32MsgData  = stDFRecvMsg.unData.u32MsgData;
        //FILT_DBG(("G u32MsgData = 0x%08lX\n", u32MsgData));
        
		/* check the filter one by one */
	    switch(u32MsgData)
	    {
	        default:
	        case DVB_FILTER_MSG_DATA_NULL:    	    
	            break;
        #if (defined(CT216S)||defined(CT216T) || defined (CT216H))	            
            case DVB_FILTER_MSG_DATA_RING_BUFFER_OVERFLOW:
                {
                    //FILT_DBG(("\n(T)FID[%ld] Ring Buffer Overflow\n", (u32)u8FID));	            
                    if (astSectionFilter[u8FID].b8Running == TRUE)
                    {
                        CT_OS_WaitOnSemaphore (&DVBFilterSemaphore, CTOS_WAIT);
                        
                        CT_PF_FilterOut(astSectionFilter[u8FID].u32PidFltNo, FALSE);	
                        CT_FILT_SetFilterType(astSectionFilter[u8FID].u32SecFltNo, FILTER_TYPE_SEC);
                        CT_FILT_ResetBuffer(astSectionFilter[u8FID].u32SecFltNo);
                        astSectionFilter[u8FID].u8AvailableSection   = 0;
                        CT_FILT_ReStart(astSectionFilter[u8FID].u32SecFltNo);
                        CT_PF_FilterOut(astSectionFilter[u8FID].u32PidFltNo, TRUE);
                        
                        CT_OS_FreeSemaphore (&DVBFilterSemaphore);
                        
                    }   
                }
                break;
        #endif //#if (defined(CT216S)||defined(CT216T))            	            
	        case DVB_FILTER_MSG_DATA_INCREASE_AVAILABLE_NUM:    	    
        		{
        			CT_OS_WaitOnSemaphore (&DVBFilterSemaphore, CTOS_WAIT);
        			
                #if (defined (CT216U)||defined (CT956))
                	astSectionFilter[u8FID].u8AvailableSection = CT_FILT_GetAvailableNum (astSectionFilter[u8FID].u32SecFltNo);
                #else
                	astSectionFilter[u8FID].u8AvailableSection ++;
                #endif
        
        			/* running and has call back function */
        			if ((astSectionFilter[u8FID].b8Running == TRUE)
        				&& (astSectionFilter[u8FID].pfCallBack != NULL))
        			{
        				/* get a section */
        				if (astSectionFilter[u8FID].u8AvailableSection)
        				{
        					if (astSectionFilter[u8FID].b8OneShot == FALSE)
        					{
        						/* countine and reset end time */
        						if(astSectionFilter[u8FID].u16TimeoutMilliSec == TIMEOUT_INFINITE)
        						{
        							astSectionFilter[u8FID].u32TimerEnd = TIMEOUT_INFINITE;
        						}
        						else
        						{
        							astSectionFilter[u8FID].u32TimerEnd = DVB_TimerGet() + (astSectionFilter[u8FID].u16TimeoutMilliSec/DVB_SYSTIME_MILSEC_PER_TICK);
        						}
        					}
        					else
        					{
        					}
        					/* call back */
        					FILT_DBG(( "{DVBFilter_Monitor_Task} Got section u8FID[0x%x]\n", u8FID));
        					if (astSectionFilter[u8FID].b8OneShot == FALSE)
        					{
        						// this while loop block other task and filter
        						u32 u32CallbackCounter = 0;
        						while(astSectionFilter[u8FID].u8AvailableSection>0)
        						{
        							u8 u8Buffer[4];
        							u16 u16SecLenInByte = 0;
        							u32 u32Size;
                
        							u32Size=CT_FILT_GetBufferFullness(astSectionFilter[u8FID].u32SecFltNo);
        							if (CT_FILT_PeekData(astSectionFilter[u8FID].u32SecFltNo, u8Buffer, 4) != DRV_OK)
        							{
        							    astSectionFilter[u8FID].u8AvailableSection = 0;
        								break;
        							}	
        							else
        							{
        								u16SecLenInByte = ((u8Buffer[1]&0x0f) << 8);
        								u16SecLenInByte |= ((u8Buffer[2]&0xff) << 0);
        								if (u16SecLenInByte > 0)
        									u16SecLenInByte += 3;
        							}
        //							FILT_DBG(("\n\r %d %ld",u8FID,u32Size));
        							if(u32Size>=u16SecLenInByte)
        							{
        								// prevent null callback
        								pfMonitorCallBack = astSectionFilter[u8FID].pfCallBack;
        
        								CT_OS_FreeSemaphore (&DVBFilterSemaphore);
        								pfMonitorCallBack (u8FID, EN_FILTER_SECTION_AVAILABLE);
        								CT_OS_WaitOnSemaphore (&DVBFilterSemaphore, CTOS_WAIT);
        							}
        
        							u32CallbackCounter++;
        							if(u32CallbackCounter==1)
        							{
        								//FILT_DBG(("dvb_filter monitor task callback n>4, PID %x, TID %x\n", astSectionFilter[u8FID].u16PID, astSectionFilter[u8FID].u16TableID));
        								break;
        							}
        
        							if ((astSectionFilter[u8FID].b8Running == FALSE)||(astSectionFilter[u8FID].pfCallBack == NULL))
        								break;
        						}
        					}
        					else
        					{
        						// prevent null callback
        						pfMonitorCallBack = astSectionFilter[u8FID].pfCallBack;
        					    
        						CT_OS_FreeSemaphore (&DVBFilterSemaphore);
        						pfMonitorCallBack (u8FID, EN_FILTER_SECTION_AVAILABLE);
        						CT_OS_WaitOnSemaphore (&DVBFilterSemaphore, CTOS_WAIT);
        					}
        					
        					/* reset the new timeout time */
        					if(astSectionFilter[u8FID].u16TimeoutMilliSec != TIMEOUT_INFINITE )
        						astSectionFilter[u8FID].u32TimerEnd = DVB_TimerGet() + (astSectionFilter[u8FID].u16TimeoutMilliSec/DVB_SYSTIME_MILSEC_PER_TICK);
        				}
        				#if 0
        				else
        				{
        					//time out ==================================================//
        					if (dvb_filterchecktimeout (u8FID))
        					{
        						FILT_DBG(( "{DVBFilter_Monitor_Task} TimeOut u8FID[0x%x]\n", u8FID));
        
        						CT_OS_FreeSemaphore (&DVBFilterSemaphore);
        						bFree = TRUE;
        						astSectionFilter[u8FID].pfCallBack (u8FID, EN_FILTER_TIMEOUT);
        
        						/* reset the new timeout time */
        						astSectionFilter[u8FID].u32TimerEnd = DVB_TimerGet() + (astSectionFilter[u8FID].u16TimeoutMilliSec/DVB_SYSTIME_MILSEC_PER_TICK);
        					}
        
        
        				}
        				#endif
        			}
        			CT_OS_FreeSemaphore (&DVBFilterSemaphore);
        
        		}
        		break;
        }
	}
}

/*! \fn void  DVB_FilterInit (void)
\brief Initial section filter when system initial.
*/
/*****************************************************************************/
EN_DRV_RESULT DVB_FilterInit(void)
{
	/*[01]error condition ===================================================*/
	//<<NONE!>>
	EN_CTOS_STATUS      status = EN_CTOS_SUCCESS;
	u8 u8FID = 0;

	if (b8FilterInitialied == TRUE)
		return DRV_OK;

	// reset filter info
	for (u8FID = 0; u8FID < MAX_FILTER_NUMBER; u8FID ++)
	{
		astSectionFilter[u8FID].u32PidFltNo = INVALID_PIDFILT_HANDLE;
		astSectionFilter[u8FID].u32SecFltNo = INVALID_FILT_HANDLE;
		astSectionFilter[u8FID].b8Running = FALSE;
		astSectionFilter[u8FID].b8Allocated = FALSE;
		astSectionFilter[u8FID].b8OneShot = TRUE;
		astSectionFilter[u8FID].u8AvailableSection = 0;
		astSectionFilter[u8FID].u16TimeoutMilliSec = TIMEOUT_INFINITE; // 0
		astSectionFilter[u8FID].pfCallBack = NULL;
		astSectionFilter[u8FID].u32TimerEnd = TIMEOUT_INFINITE; // 0
		astSectionFilter[u8FID].pu8RingBufferAddress = NULL;
	}

	/*[02]set CT_FILTER ====================================================*/

#ifdef CT216E
	#ifdef CT_INSTANT_DELAY
	if (CT_DEMUX_Initial_InstantDelay() != DRV_OK)
	{
			FILT_DBG(( "CT_DEMUX_Initial FAIL\n"));
			return DRVERR_NOTOK;
	}			
	#else
	if (CT_DEMUX_Initial () != DRV_OK)
	{
		FILT_DBG(( "CT_DEMUX_Initial FAIL\n"));
		return DRVERR_NOTOK;
	}
	#endif
#endif
#if defined(CT216S)||defined(CT216T)||defined(CT216H)
    if (CT_DEMUX_Initial () != DRV_OK)
	{
		FILT_DBG(( "CT_DEMUX_Initial FAIL\n"));
		return DRVERR_NOTOK;
	}
#endif
	if (CT_FILT_Initial ()!= DRV_OK)
	{
		FILT_DBG(( "CT_FILT_Initial FAIL\n"));
		return DRVERR_NOTOK;
	}
	

	status = CT_OS_CreateTask (&stDVBFilterTask,
								"DVBFLT",
								DVBFilter_Monitor_Task,
								&u8DVBFilterTaskStack[0],
								DVB_FILTER_TASK_STACK_SIZE,
								TASK_PRIORITY_DVB_FILTER,
								DVB_FILTER_TASK_TIMESLICE);

	if (status != EN_CTOS_SUCCESS)
	{
		FILT_DBG(( "Create Filter Task Fail\n"));
		return DRVERR_NOTOK;
	}
	status = CT_OS_CreateTask (&stDVBTimerTask,
								"DVBTIMER",
								DVBFilter_Timer_Task,
								&u8DVBTimerTaskStack[0],
								DVB_FILTER_TIMER_TASK_STACK_SIZE,
								TASK_PRIORITY_DVB_FILTER_TIMER,
								DVB_FILTER_TIMER_TASK_TIMESLICE);

	if (status != EN_CTOS_SUCCESS)
	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -