📄 dvb_filt.c
字号:
/******************************************************************************
(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 + -