www.pudn.com > tvctrl.rar > tvctrl.c


/*  
	描述:	电视控制模块(数字电视或模块电视)  
			  
*/  
  
#include   
#include   
#include   
#include   
  
#include   
#include   
#include "atvdtv.h"  
#include "channeldb.h"  
  
  
#define EXT_SHAREDATA_LASTCHA		0  
#define EXT_SHAREDATA_CURRCHA		1  
#define EXT_SHAREDATA_TOTALCHAS 	2  
#define EXT_SHAREDATA_CHADBSTATE	3  
  
extern int SetExtShareData(int type,int value);  
  
/*从供外部使用的共享缓冲区取数据,  
type:0~9;  
返回:共享缓冲区中的值*/  
extern int GetExtShareData(int type);  
  
  
#define CXX_DEBUG(x...)  
#define GLH_DEBUG(x...)  
  
typedef struct tagTvCtrl  
{  
	TVSpecial *tvspecial ;  
	TVChannelInfo *tvinfo ;  
	int tunerhandle ;	// 高频头模块控制句柄  
	int path ;  
	int bDTV ;  
} TvCtrl_t, *pTvCtrl_t ;  
  
static int DTVSearch(int path, DTVSpecial *special,  
				int searchtype, LPFUNCTVSEARCH callback, unsigned long callbackParam) ;  
static int ATVSearch(int path, ATVSpecial *special,  
				int searchtype, LPFUNCTVSEARCH callback, unsigned long callbackParam) ;  
	  
  
static TvCtrl_t * tc_hTV = NULL;  
static int tc_nTVShares = 0;  
  
static const int AtvMinDiv = (int)((ATV_FRQ_MIN+TUNER_IF) * 16.0) ;  
static const int AtvMaxDiv = (int)((ATV_FRQ_MAX+TUNER_IF) * 16.0) ;  
  
HW_HANDLE Hw_OpenTV(int path,int bDTV)  
{  
	HW_HANDLE result = 0 ;  
	int tunerhandle = 0 ;  
	int err = 0 ;  
	TvCtrl_t *tv_ctrl;  
	  
	if(tc_hTV)  
	{  
		tc_nTVShares ++;  
		return (int)tc_hTV;  
	}  
	  
	tv_ctrl = (TvCtrl_t *)malloc(sizeof(TvCtrl_t)) ;  
		  
	if (tv_ctrl)  
	{  
		memset(tv_ctrl, 0x00, sizeof(TvCtrl_t)) ;  
		tv_ctrl->tvspecial = (TVSpecial *)malloc(sizeof(TVSpecial)) ;  
		tv_ctrl->tvinfo = (TVChannelInfo *)malloc(sizeof(TVChannelInfo)) ;  
		if (!(tv_ctrl->tvspecial  
				&& tv_ctrl->tvinfo)  
				)  
		{  
			err = 1 ;  
			goto done ;	  
		}  
		memset(tv_ctrl->tvspecial, 0x00, sizeof(TVSpecial)) ;  
		memset(tv_ctrl->tvinfo, 0x00, sizeof(TVChannelInfo)) ;  
		  
		if (bDTV)  
		{  
			  
		}  
		else  
		{  
			tunerhandle = AtvTunerOpen(path) ;  
			if (tunerhandle == 0)  
			{  
				err = 1 ;  
				goto done ;	  
			}  
			tv_ctrl->tunerhandle = tunerhandle ;  
			tv_ctrl->tvspecial->tvtype = TVTYPE_ATV ;  
			tv_ctrl->bDTV = 0 ;  
			result = (HW_HANDLE)tv_ctrl ;  
		}  
	}  
	if (result)  
		InitChannelDB() ;  
		  
	tc_hTV = tv_ctrl;  
	tc_nTVShares = 1;  
	  
done:  
	if (err)  
	{  
		if (tv_ctrl) {free(tv_ctrl) ; tv_ctrl = NULL ; }  
	}  
	  
	return (result) ;  
}  
  
/*与Hw_OpenTV()成对出现*/  
//2、	  
int Hw_CloseTV(HW_HANDLE handle)  
{  
	int result = -1 ;  
	  
	TvCtrl_t *tv_ctrl = (TvCtrl_t *)handle ;  
	  
	tc_nTVShares--;  
	if(tc_nTVShares > 0)  
		return 0;  
		  
	if (tv_ctrl)  
	{  
		/* close tuner */  
		if (tv_ctrl->bDTV)  
		{  
  
		}  
		else  
		{  
			if (tv_ctrl->tunerhandle) AtvTunerClose(tv_ctrl->tunerhandle) ;  
		}  
		if (tv_ctrl->tvspecial) free(tv_ctrl->tvspecial) ;  
		if (tv_ctrl->tvinfo) free(tv_ctrl->tvinfo) ;  
		free(tv_ctrl) ;  
		tv_ctrl = NULL ;  
		result = 0 ;  
	}  
	if (result == 0)  
		CloseChannelDB() ;  
	  
	tc_hTV = NULL;  
	tc_nTVShares = 0;  
	return (result) ;  
}  
  
/*设置电视的详细相关信息,handle是Hw_OpenTV打开后的句柄*/  
//3、	  
int Hw_SetTVSpecial(HW_HANDLE handle,TVSpecial *pspecial)  
{  
	int result = -1 ;  
  
	TvCtrl_t *tv_ctrl = (TvCtrl_t *)handle ;  
	  
	if (tv_ctrl  
		&& pspecial  
		&& tv_ctrl->tvspecial  
		)  
	{  
		memcpy(tv_ctrl->tvspecial, pspecial, sizeof(TVSpecial)) ;  
		result = 0 ;  
	}  
	  
	return (result) ;  
}  
  
//4、	  
int Hw_GetTVSpecial(HW_HANDLE handle,TVSpecial ** ppspecial)  
{  
	int result = -1 ;  
	  
	TvCtrl_t *tv_ctrl = (TvCtrl_t *)handle ;  
	  
	if (tv_ctrl  
		&& tv_ctrl->tvspecial  
		)  
	{  
		if (ppspecial)  
			*ppspecial = tv_ctrl->tvspecial ;  
		result = 0 ;  
	}  
	  
	return (result) ;  
}  
  
/*切换到指定频道:handle是Open函数打开后的句柄,tvinfo是要打开的节目的详细物理信息*/  
//5、	  
int Hw_TuneToTV(HW_HANDLE handle,TVChannelInfo* tvinfo)  
{  
	int result = -1 ;  
	  
	TvCtrl_t *tv_ctrl = (TvCtrl_t *)handle ;  
	  
	if (tv_ctrl  
		&& tvinfo	  
		)  
	{  
		if (tv_ctrl->tvinfo == NULL)  
			tv_ctrl->tvinfo = (TVChannelInfo *)malloc(sizeof(TVChannelInfo)) ;  
			  
		if (tv_ctrl->tvinfo)  
		{  
			memcpy(tv_ctrl->tvinfo, tvinfo, sizeof(TVChannelInfo)) ;  
		}  
		  
		if (tv_ctrl->bDTV)  
		{  
			  
		}  
		else  
		{  
			result = AtvTuneTo(tv_ctrl->tunerhandle, &(tvinfo->info.atv)) ;  
		}  
	}  
	  
	return (result) ;  
}  
  
/*取得高频道状态*/  
//6、  
int Hw_TuneStateGet(HW_HANDLE handle, int *state)  
{  
	int result = -1 ;  
	  
	TvCtrl_t *tv_ctrl = (TvCtrl_t *)handle ;  
	  
	if (tv_ctrl  
		&& state	  
		)  
	{  
		if (tv_ctrl->bDTV)  
		{  
			  
		}  
		else  
		{  
			result = AtvGetState(tv_ctrl->tunerhandle, state) ;  
		}  
	}  
	  
	return (result) ;  
}  
  
/*搜台:handle是打开的句柄,  
searchtype:0:普通搜台,1快速搜台;  
callback:是接收搜台信息用的回调函数*/  
//6、	  
int Hw_TVSearch(HW_HANDLE handle,  
				int searchtype,LPFUNCTVSEARCH callback)  
{  
	int result = -1 ;  
	  
	TvCtrl_t *tv_ctrl = (TvCtrl_t *)handle ;  
	  
	if (tv_ctrl  
		&& tv_ctrl->tvspecial  
		&& (searchtype == 0 || searchtype == 1)  
		&& callback  
		)  
	{  
		if (tv_ctrl->tvspecial->tvtype == TVTYPE_ATV  
			&& tv_ctrl->bDTV == 0  
			)  
		{  
			result = ATVSearch(tv_ctrl->path, &(tv_ctrl->tvspecial->special.atv),  
						searchtype, callback, (unsigned long)handle) ;  
		}  
		else  
		if (tv_ctrl->tvspecial->tvtype == TVTYPE_DTV  
			&& tv_ctrl->bDTV  
			)  
		{  
			result = DTVSearch(tv_ctrl->path, &(tv_ctrl->tvspecial->special.dtv),  
						searchtype, callback, (unsigned long)handle) ;  
		}  
	}  
	  
	return (result) ;  
}  
  
static int DTVSearch(int path, DTVSpecial *special,  
				int searchtype, LPFUNCTVSEARCH callback, unsigned long callbackParam)  
{  
	int result = -1 ;  
	  
	return (result) ;  
}  
  
static int ATVSearch(int path, ATVSpecial *special,  
				int searchtype, LPFUNCTVSEARCH callback, unsigned long callbackParam)  
{  
	int result = -1 ;  
	TvCtrl_t *p ;  
	  
	p = (TvCtrl_t *)callbackParam ;  
	if (p)  
	{  
		if (searchtype == 0)  
		{  
			result = AtvNormalTestTuner(p->tunerhandle, special,(LPFUNCATVSEARCH)callback, callbackParam) ;	  
		}  
		else  
		{  
			result = AtvQuickTestTuner(p->tunerhandle, special, (LPFUNCATVSEARCH)callback, callbackParam) ;	  
		}  
	}  
	  
	return (result) ;  
}  
  
/*=================================================================*/  
/*=================================================================*/  
/*切换到指定频道的电视,handle是调用Hw_OpenTV ()打开的句柄;  
tvid:频道号,1~300是模拟电视频道,300~900是数字电视,1000以上是功能频道*/  
int TuneToTV(HW_HANDLE handle,int tvid)  
{  
	int result = -1 ;  
	TVChannelInfo *tvinfo, info ;  
	  
	if (handle)  
	{  
		tvinfo = GetChannelPhysInfo(tvid) ;  
		GLH_DEBUG("\nTuneToTV>>>tvinfo=%08x,tvid=%d",(unsigned int)tvinfo, tvid);  
		if (tvinfo)  
		{  
			memcpy(&info, tvinfo, sizeof(TVChannelInfo)) ;  
			if (Hw_TuneToTV(handle, &info) == 0)  
			{  
				//SetCurrentChannelId(tvid) ;  
				result = 0 ;  
			}  
		}  
		else  
		{/*change to default:*/  
			memset(&info,0,sizeof(TVChannelInfo));  
			info.info.atv.ndiv = 1404 ; 
			info.info.atv.bvalid = 1 ;  
			info.tvtype = TVTYPE_ATV;  
			  
			if (Hw_TuneToTV(handle, &info) == 0)  
			{  
				//SetCurrentChannelId(tvid) ;  
				result = 0 ;  
			}  
		}  
		GLH_DEBUG("\nTuneToTV>>> result=%d",result);  
	}  
	  
	return (result) ;  
}  
  
/*相对当前频道换台,step>0向前步进,<0向后步进*/  
int TuneStepTV (HW_HANDLE handle,int step)  
{  
	int result = -1 ;  
	TVChannelInfo *tvinfo, info ;  
	  
	if (handle)  
	{  
		int r, i ;   
		int *rarr = NULL ;  
		  
		r = FilterChannelDB(NULL, FILTER_MASK_ALL_ATV, &rarr) ;  
		if (r > 1  
			&& rarr  
			&& (step > 0 || step < 0)  
			)  
		{  
			int ch = GetCurrentChannelId() ;  
			int max = -1 ;  
			int min = 1000000 ;  
			int prev = -1 ;  
			int next = 1000000 ;  
				  
			for (i=0; i max) max = rarr[i] ;  
				if (rarr[i] < min) min = rarr[i] ;  
				if (rarr[i] > ch  
					&& rarr[i] < next  
					)  
					next = rarr[i] ;  
				if (rarr[i] < ch  
					&& rarr[i] > prev  
					)  
					prev = rarr[i] ;  
					  
				if (step > 0)  
				{  
					if (next != 1000000) ch = next ;  
					else if (min != 1000000) ch = min ;  
					break ;  
				}  
				else if (step < 0)  
				{  
					if (prev != -1) ch = prev ;  
					else if (max != -1) ch = max ;  
					break ;  
				}  
			} /* end for() */  
			if (ch != GetCurrentChannelId())  
			{  
				tvinfo = GetChannelPhysInfo(ch) ;  
				if (tvinfo)  
				{  
					memcpy(&info, tvinfo, sizeof(TVChannelInfo)) ;  
					Hw_TuneToTV(handle, &info) ;  
					//SetCurrentChannelId(ch) ;  
					result = 0 ;  
				}  
			}  
		}  
	}  
	  
	return (result) ;  
}  
  
/*相对当前频道微调,substep为微调值,以1/16MHZ为单位。>0几前调,<0向后调*/  
/*resultdiv为实际频率值,以1/16MHZ为单位*/  
int TuneSubTV(HW_HANDLE handle,int substep, int *resultdiv)  
{  
	int result = -1 ;  
	TVChannelInfo *tvinfo, info ;  
	TvCtrl_t *p = (TvCtrl_t *)handle ;  
	  
	if (p  
		&& p->bDTV == 0  
		&& (substep > 0 || substep < 0)  
		)  
	{  
		tvinfo = GetChannelPhysInfo(GetCurrentChannelId()) ;  
		if (tvinfo)  
		{  
			memcpy(&info, tvinfo, sizeof(TVChannelInfo)) ;  
			if (substep > 0  
				|| substep < 0  
				)  
				info.info.atv.ndiv += substep ;  
			else  
				goto done ;  
  
			if (info.info.atv.ndiv < AtvMinDiv)  
			{  
				info.info.atv.ndiv = AtvMaxDiv - ((AtvMinDiv-info.info.atv.ndiv-1)%(AtvMaxDiv-AtvMinDiv+1)) ;  
			}  
			else  
			if (info.info.atv.ndiv > AtvMaxDiv)  
			{  
				info.info.atv.ndiv = AtvMinDiv + ((info.info.atv.ndiv-AtvMaxDiv-1)%(AtvMaxDiv-AtvMinDiv+1)) ;  
			}  
			  
			if (resultdiv)  
				*resultdiv = info.info.atv.ndiv ;  
				  
			result = Hw_TuneToTV(handle, &info) ;  
		}  
	}  
	  
done:  
	return (result) ;  
}  
  
/*相对当前频道微调,divbase 起始频点,以1/16MHZ为单位; substep为微调值,以1/16MHZ为单位。>0几前调,<0向后调*/  
/*resultdiv为实际频率值,以1/16MHZ为单位*/  
int TuneSubTVEx(HW_HANDLE handle,int divbase, int substep, int *resultdiv)  
{  
	int result = -1 ;  
	TVChannelInfo *tvinfo, info ;  
	TvCtrl_t *p = (TvCtrl_t *)handle ;  
	  
	if (p  
		&& p->bDTV == 0  
		&& (substep > 0 || substep < 0)  
		)  
	{  
		bzero(&info, sizeof(TVChannelInfo)) ;  
		if (divbase < AtvMinDiv  
			|| divbase > AtvMaxDiv  
			)  
		{  
			if ((tvinfo = GetChannelPhysInfo(GetCurrentChannelId())))  
				memcpy(&info, tvinfo, sizeof(TVChannelInfo)) ;  
		}  
		else  
		{  
			info.tvtype = TVTYPE_ATV ;  
			info.info.atv.ndiv = divbase ;  
		}  
			  
		if (info.info.atv.ndiv)  
		{  
			if (substep > 0  
				|| substep < 0  
				)  
				info.info.atv.ndiv += substep ;  
			else  
				goto done ;  
				  
			if (info.info.atv.ndiv < AtvMinDiv)  
			{  
				info.info.atv.ndiv = AtvMaxDiv - ((AtvMinDiv-info.info.atv.ndiv-1)%(AtvMaxDiv-AtvMinDiv+1)) ;  
			}  
			else  
			if (info.info.atv.ndiv > AtvMaxDiv)  
			{  
				info.info.atv.ndiv = AtvMinDiv + ((info.info.atv.ndiv-AtvMaxDiv-1)%(AtvMaxDiv-AtvMinDiv+1)) ;  
			}  
			  
			if (resultdiv)  
				*resultdiv = info.info.atv.ndiv ;  
				  
			result = Hw_TuneToTV(handle, &info) ;  
		}  
	}  
	  
done:  
	return (result) ;  
}  
  
int TuneStateGet(HW_HANDLE handle, int *state)  
{  
	return Hw_TuneStateGet(handle, state) ;	  
}  
  
/*  
五、	模拟电视搜台模块:本模块处理"高频头模块"回调来的节目信息,存入数据库中,并把结果传给用户界面。  
*/  
  
static LPFUNCTVSEARCH usercallback = NULL ;  
static int SearchedCount = 0 ;  
static int StartChannelId = 0 ;  
static LocalChannelRecord	*pLocalChannel = NULL ;  
static TVChannelInfo		*pTVChannel = NULL ;  
static TVINFO				*pTVInfo = NULL ;  
static char 				*pFlags = NULL ;  
static int					filtedNums = 0 ;  
  
static int SetSearchCallBackParam(int type, int param)  
{  
	int result = -1 ;  
	  
	/* 设置回调函数并初始化其它变量 */  
	if (type == 0)  
	{  
		usercallback = (LPFUNCTVSEARCH)param ;  
		SearchedCount = 0 ;  
		pLocalChannel = NULL ;  
		pTVChannel = NULL ;  
		pTVInfo = NULL ;  
		filtedNums = 0 ;  
		result = 0 ;  
	}  
	/* 设置起始频道号 */  
	else  
	if (type == 1)  
	{  
		StartChannelId = param ;  
		result = 0 ;  
	}  
	  
	return (result) ;  
}  
  
static int SearchCallback(HW_HANDLE handle,TVChannelInfo * tvinfo,unsigned int status)  
{  
	int result = 0 ;  
	int r ;  
	int chid = -1 ;  
	LocalChannelRecord logic ;  
	  
	bzero(&logic, sizeof(LocalChannelRecord)) ;  
	  
	CXX_DEBUG("\nIn TVCTRL,SearchCallback>>>status=%d",status);  
	  
	/* 第一次搜索回调 */  
	if (SearchedCount == 0  
		&& tvinfo  
		)  
	{  
		if (tvinfo->tvtype == TVTYPE_ATV)  
		{  
			if (StartChannelId < ATV_CHANNELID_START  
				|| StartChannelId > ATV_CHANNELID_END  
				)  
				StartChannelId = ATV_CHANNELID_START ;  
		}  
		else  
		if (tvinfo->tvtype == TVTYPE_DTV)  
		{  
			/* 数字电视与模拟电视处理方式不一样 */  
			if (StartChannelId < DTV_CHANNELID_START  
				|| StartChannelId > DTV_CHANNELID_END  
				)  
				StartChannelId = DTV_CHANNELID_START ;  
		}  
		else  
		{  
			/* 非法 */  
			CXX_DEBUG("\nIn TVCTRL,SearchCallback>>>1status=%d",status);  
			goto done ;  
		}  
	}  
	  
	chid = StartChannelId + SearchedCount ;  
	/* 若超出范围,从相关起始频道号开始 */  
	if (tvinfo)  
	{  
		if (tvinfo->tvtype == TVTYPE_ATV)  
		{  
			if (chid < ATV_CHANNELID_START  
				|| chid > ATV_CHANNELID_END  
				)  
				chid = ATV_CHANNELID_START + (chid%(ATV_CHANNELID_END+1)) ;  
		}  
		else  
		if (tvinfo->tvtype == TVTYPE_DTV)  
		{  
			if (chid < DTV_CHANNELID_START  
				|| chid > DTV_CHANNELID_END  
				)  
				chid = DTV_CHANNELID_START + (chid%(DTV_CHANNELID_END+1)) ;  
		}  
		else  
		{  
			/* 非法 */  
			CXX_DEBUG("\nIn TVCTRL,SearchCallback>>>2status=%d",status);  
			goto done ;  
		}  
	}  
	  
	if (usercallback)  
	{  
		TVChannelInfo tmpinfo ;  
		  
		bzero(&tmpinfo, sizeof(TVChannelInfo)) ;  
		if (tvinfo)  
			tmpinfo = *tvinfo ;  
		  
		if (tmpinfo.tvtype == TVTYPE_ATV) tmpinfo.info.atv.nchid = chid ;  
		else  
		if (tmpinfo.tvtype == TVTYPE_DTV) tmpinfo.info.dtv.tvid = chid ;  
		r = usercallback(handle, &tmpinfo, status) ;  
		  
		/***** 注意: 指定的频道号减1 (2005-06-23)*****/  
		  
		if (tmpinfo.tvtype == TVTYPE_ATV  
			&& (r-1) >= ATV_CHANNELID_START  
			&& (r-1) <= ATV_CHANNELID_END  
			)  
		{  
			chid = (r-1) ;  
		}  
		else  
		if (tmpinfo.tvtype == TVTYPE_DTV  
			&& (r-1) >= DTV_CHANNELID_START  
			&& (r-1) <= DTV_CHANNELID_END  
			)  
		{  
			chid = (r-1) ;  
		}  
		else  
		{  
			chid = -1 ;	  
		}  
		GLH_DEBUG("\nIn TVCTRL,SearchCallback>>>r=%d",r);  
		if (r > 0) result = 1 ;  
	}  
	else  
	{  
		/* 持续不中断 */  
		result = 1 ;  
	}  
	  
	if (status == TV_SEARCH_CONT  
		&& tvinfo  
		)  
	{  
		int ch = AddChannelEx(NULL, tvinfo, NULL, ADDCHANNEL_FLGAS_AUTOMATCH) ;  
		  
		if (  
			((ch >= ATV_CHANNELID_START) && (ch <= ATV_CHANNELID_END))  
			|| ((ch >= DTV_CHANNELID_START) && (ch <= DTV_CHANNELID_END))  
			|| ((ch >= FTV_CHANNELID_START) && (ch <= FTV_CHANNELID_END))  
			)  
			  
			//SetCurrentChannelId(ch) ;  
		SearchedCount++ ;  
	}  
	else if (status == TV_SEARCH_FINISH)  
	{  
		/*UpdateChannelDB() ;*/  
		SearchedCount = 0 ;  
	}  
	else  
	{  
		/*result = 1 ;*/  
	}  
	  
done:  
	GLH_DEBUG("\nTVCTRL callback,result=%d",result);  
	return (result) ;  
}  
  
static int bak_SearchCallback(HW_HANDLE handle,TVChannelInfo * tvinfo,unsigned int status)  
{  
	int result = 0 ;  
	int r ;  
	int i, j ;  
	int chid ;  
	LocalChannelRecord logic ;  
	char name[24] ;  
	  
	bzero(&logic, sizeof(LocalChannelRecord)) ;  
	  
	/* 非法 */  
	if (tvinfo == NULL)  
		goto done ;  
	  
	/* 第一次搜索回调 */  
	if (SearchedCount == 0)  
	{  
		int *pr = NULL ;  
		int nums = 0 ;  
		int err = 0 ;	/* 未出错 */  
  
		if (tvinfo->tvtype == TVTYPE_ATV)  
		{  
			nums = FilterChannelDB(NULL, FILTER_MASK_ALL_ATV, &pr) ;  
			if (StartChannelId < ATV_CHANNELID_START  
				|| StartChannelId > ATV_CHANNELID_END  
				)  
				StartChannelId = ATV_CHANNELID_START ;  
		}  
		else  
		if (tvinfo->tvtype == TVTYPE_DTV)  
		{  
			/* 数字电视与模拟电视处理方式不一样 */  
			/*  
			nums = FilterChannelDB(NULL, FILTER_MASK_ALL_DTV, &pr) ;  
			*/  
			if (StartChannelId < DTV_CHANNELID_START  
				|| StartChannelId > DTV_CHANNELID_END  
				)  
				StartChannelId = DTV_CHANNELID_START ;  
		}  
		else  
		{  
			/* 非法 */  
			goto done ;  
		}  
		  
		if (nums > 0  
			&& pr  
			)  
		{  
			size_t size0 = (size_t)(sizeof(LocalChannelRecord)*nums) ;  
			size_t size1 = (size_t)(sizeof(TVChannelInfo)*nums) ;  
			size_t size2 = (size_t)(sizeof(TVINFO)*nums) ;  
			size_t size3 = (size_t)(sizeof(char)*nums) ;  
			  
			pLocalChannel	=	(LocalChannelRecord *)malloc(size0) ;  
			pTVChannel		=	(TVChannelInfo *)malloc(size1) ;  
			pTVInfo			=	(TVINFO *)malloc(size2) ;  
			pFlags			=	(char *)malloc(size3) ;  
			if (pLocalChannel  
				&& pTVChannel  
				&& pTVInfo  
				&& pFlags  
				)  
			{  
				bzero(pLocalChannel, size0) ;  
				bzero(pTVChannel, size1) ;  
				bzero(pTVInfo, size2) ;  
				bzero(pFlags, size3) ;  
				  
				filtedNums = nums ;  
				/* 导出所有相关数据 */  
				for (i=0; i= 0)  
					{  
						void *p ;  
						  
						p = (void *)GetChannelLogicInfo(pr[i]) ;  
						if (p) memcpy(&(pLocalChannel[i]), p, sizeof(LocalChannelRecord)) ;  
						p = (void *)GetChannelPhysInfo(pr[i]) ;  
						if (p) memcpy(&(pTVChannel[i]), p, sizeof(TVChannelInfo)) ;  
						p = (void *)GetChannelName(pr[i]) ;  
						if (p) strncpy(pTVInfo[i].name, (char *)p, sizeof(pTVInfo[i].name)-1) ;  
					}  
				}  
			}  
			/* 不能分配内存,搜索但不能写数据库 */  
			else  
			{  
#ifdef __DEBUG_  
				printf("malloc() error In SearchCallback()! \n") ;  
#endif  
				if (pLocalChannel)	{free(pLocalChannel);	pLocalChannel = NULL ; }  
				if (pTVChannel)		{free(pTVChannel);		pTVChannel = NULL ; }  
				if (pTVInfo)		{free(pTVInfo);			pTVInfo = NULL ; }  
				if (pFlags)			{free(pFlags);			pFlags = NULL ;}  
				err = 1 ;  
			}  
		}  
		  
		/* 未发生差错,清空相关信息 */  
		if (err == 0)  
			EmptyChannelDB(tvinfo->tvtype) ;  
	}  
	  
	chid = StartChannelId + SearchedCount ;  
	/* 若超出范围,从相关起始频道号开始 */  
	if (tvinfo->tvtype == TVTYPE_ATV)  
	{  
		if (chid > ATV_CHANNELID_END  
			)  
			chid = ATV_CHANNELID_START + (chid%(ATV_CHANNELID_END+1)) ;  
	}  
	else  
	if (tvinfo->tvtype == TVTYPE_DTV)  
	{  
		if (chid < DTV_CHANNELID_START  
			|| chid > DTV_CHANNELID_END  
			)  
			chid = DTV_CHANNELID_START + (chid%(DTV_CHANNELID_END+1)) ;  
	}  
	else  
	{  
		/* 非法 */  
		goto done ;  
	}  
	  
	if (usercallback)  
	{  
		TVChannelInfo tmpinfo = *tvinfo ;  
		  
		if (tmpinfo.tvtype == TVTYPE_ATV) tmpinfo.info.atv.nchid = chid ;  
		else  
		if (tmpinfo.tvtype == TVTYPE_DTV) tmpinfo.info.dtv.tvid = chid ;  
		r = usercallback(handle, &tmpinfo, status) ;  
		if (tmpinfo.tvtype == TVTYPE_ATV  
			&& r >= ATV_CHANNELID_START  
			&& r <= ATV_CHANNELID_END  
			)  
		{  
			chid = r ;  
		}  
		else  
		if (tmpinfo.tvtype == TVTYPE_DTV  
			&& r >= DTV_CHANNELID_START  
			&& r <= DTV_CHANNELID_END  
			)  
		{  
			chid = r ;  
		}  
		if (r >= 0) result = 1 ;  
	}  
	else  
	{  
		/* 持续不中断 */  
		result = 1 ;  
	}  
	  
	if (status == TV_SEARCH_CONT)  
	{  
		if (tvinfo->tvtype == TVTYPE_ATV)  
		{  
			/* 搜索频道表,找到频率相匹配项 */  
#ifdef __DEBUG__  
printf ("==============\n") ;  
#endif  
			for (i=0; iinfo.atv.ndiv=%d, pTVChannel[i].info.atv.ndiv=%d \n",  
								tvinfo->info.atv.ndiv, pTVChannel[i].info.atv.ndiv) ;  
#endif  
				if (tvinfo->info.atv.ndiv >= (pTVChannel[i].info.atv.ndiv-16)  
					&& tvinfo->info.atv.ndiv <= (pTVChannel[i].info.atv.ndiv+16)  
					)  
				{  
					TVChannelInfo info  ;  
#ifdef __DEBUG__  
					printf("tvinfo->info.atv.ndiv=%d, pTVChannel[i].info.atv.ndiv=%d \n",  
								tvinfo->info.atv.ndiv, pTVChannel[i].info.atv.ndiv) ;  
#endif  
					memcpy(&info, tvinfo, sizeof(TVChannelInfo)) ;  
					memcpy(&logic, &(pLocalChannel[i]), sizeof(LocalChannelRecord)) ;  
					info.info.atv.nchid = pTVChannel[i].info.atv.nchid ;  
					logic.channelid = chid ;  
					r = AddChannel(pTVInfo[i].name, &info, &logic) ;  
					/* 更新成功 */  
					if (r == 0)  
					{  
						SearchedCount++ ;  
						/* 频道占用标志 */  
						for (j=0; j= filtedNums)  
			{  
				logic.channelid = chid ;  
				logic.tvtype = tvinfo->tvtype ;  
				sprintf(name, "未命名") ;  
				r = AddChannel(name, tvinfo, &logic) ;  
				/* 更新成功 */  
				if (r == 0)  
				{  
					SearchedCount++ ;  
				}  
				else  
				{  
#ifdef __DEBUG__  
					printf("AddChannel() 1 error \n") ;  
#endif				  
				}  
			}  
		}  
		else  
		if (tvinfo->tvtype == TVTYPE_DTV)  
		{  
			logic.channelid = SearchedCount ;  
			logic.tvtype = tvinfo->tvtype ;  
			sprintf(name, "未命名") ;  
			r = AddChannel(name, tvinfo, &logic) ;  
			if (r == 0)  
			{  
				SearchedCount++ ;  
			}  
			else  
			{  
#ifdef __DEBUG__  
				printf("AddChannel() 2 error \n") ;  
#endif				  
			}  
		}  
	}  
	else  
	if (status == TV_SEARCH_FINISH)  
	{  
		if (tvinfo->tvtype == TVTYPE_ATV)  
		{  
			/* 更新未被在搜索中冲除的频道 */  
			for (i=0; i 0)  
				UpdateChannelDB() ;	  
		}  
		else  
		if (tvinfo->tvtype == TVTYPE_DTV)  
		{  
			/*搜索台结束,保存之 */  
			if (SearchedCount > 0)  
				UpdateChannelDB() ;	  
		}  
		  
		/* 搜索结束,进行清理 */  
		SearchedCount = 0 ;  
		if (pLocalChannel)	{free(pLocalChannel);	pLocalChannel = NULL ;}  
		if (pTVChannel) 	{free(pTVChannel);		pTVChannel = NULL ;}  
		if (pTVInfo)		{free(pTVInfo);			pTVInfo = NULL ;}  
		if (pFlags)			{free(pFlags);			pFlags = NULL ;}  
		if (filtedNums) 	filtedNums = 0 ;  
	}  
	  
done:  
	return (result) ;  
}  
  
/*参照高频头控制模块,回调函数由应用界面调用,一般用于显示节目信息给用户,并可被用户中断搜台过程。*/  
int SearchTV(HW_HANDLE handle, int type, LPFUNCTVSEARCH callback,  
			unsigned int status)  
{  
	int result = -1 ;  
	  
	if (handle  
		&& (type == 0 || type == 1)  
		)  
	{  
		SetSearchCallBackParam(0, (int)callback) ;  
		SetSearchCallBackParam(1, status) ;  
		  
		result = Hw_TVSearch(handle, type, SearchCallback) ;  
		  
		SetSearchCallBackParam(0, (int)NULL) ;  
		SetSearchCallBackParam(1, 0) ;  
	}  
	  
	return (result) ;  
}  
  
int GetCurrentChannelId()  
{  
	return GetExtShareData(EXT_SHAREDATA_CURRCHA);  
}  
  
int SetCurrentChannelId(int channelid)  
{  
	int result = -1 ;  
	short tmpid ;  
  
	tmpid = (short)channelid ;  
	result = SetE2PuserInfo(E2PCURCHA, &tmpid, 2);  
	if (result < 0)  
	{  
			GLH_DEBUG("\n >>> SetCurrentChannelId(%d)-->SetE2PuserInfo() error \n", (int)tmpid) ;  
	}  
	return 0 ;  
}  
  
int Hw_SetChannelPicMode(HW_HANDLE handle, int mode)  
{  
	int result = -1 ;  
	  
	return (result) ;  
}  
  
int Hw_SetChannelSndMode(HW_HANDLE handle, int mode)  
{  
	int result = -1 ;  
	TvCtrl_t *tv_ctrl = (TvCtrl_t *)handle ;  
	  
	if (tv_ctrl  
		&& tv_ctrl->tunerhandle  
		)  
	{  
		switch (mode)  
		{  
			case TUNER_SOUND_BG:  
			case TUNER_SOUND_I:  
			case TUNER_SOUND_DK:  
			case TUNER_SOUND_M:  
			case TUNER_SOUND_L:  
			{	  
				TVChannelInfo *tvinfo ;  
				  
				tvinfo = GetChannelPhysInfo(GetCurrentChannelId()) ;  
				GLH_DEBUG("\nHw_SetChannelSndMode>>>tvinfo=%08x",tvinfo);  
				if(tvinfo)  
				{  
					AtvTunerSetSndMode(tv_ctrl->tunerhandle, &(tvinfo->info.atv),mode) ;  
				}  
				result = 0 ;  
			}  
  
			default:  
				break ;  
		}  
	}  
	  
	return (result) ;  
}  
  
int Hw_Set7400Source(HW_HANDLE handle, int source)  
{  
	int result = -1 ;  
	int hAdv7400 = 0 ;  
	  
	Adv7400_Open(&hAdv7400) ;  
	if (hAdv7400)  
	{  
		Adv7400_SetSource(hAdv7400, source) ;  
		result = 0 ;  
		Adv7400_Close(hAdv7400) ;  
	}  
		  
	return (result) ;	  
}  
  
#if 1  
  
#include "tda9332.h"  
int Hw_Init9332(HW_HANDLE handle)  
{  
	p_9332_startup(0) ;  
	  
	return (0) ;  
}  
#endif