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

📄 dvb_pvr.c

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

        (C)Copyright Cheertek Inc.
           K000, all right reserved.
 
        Date    : 2006.02.21
        Author  : Cheertek (k000)
        Purpose : PVR API for UI Layer
****************************************************************************/
#include <stdio.h>
#include <string.h>
#include "dvb_pvr.h"
//#include "dvb_av.h"
#include "dvb_sys.h"
#include "dvb_file.h"
//#include "dvb_filt.h"
#include "ct_os.h"
#include "ct_video.h"
#include "ct_filter.h"
#include "task_cfg.h"
#include "ct_audio.h"
#include "PVR\pvr_porting.h"
#include "PVR\pvr_kernel.h"
#include "dvb_usb.h"
//#include "dvb_fp.h"
//#include "ct_nim.h"
 
#define	PVR_QUEUE_SIZE	1024

#ifdef PVR_ENLARGE_BUFFER
#define DVB_PVR_RECODR_BUFFER_RATION_UPPER					5
#define DVB_PVR_RECODR_BUFFER_RATION_LOWER					4
#else
#define DVB_PVR_RECODR_BUFFER_RATION_UPPER					30
#define DVB_PVR_RECODR_BUFFER_RATION_LOWER					15
#endif

#define	DVB_PVR_PLAY_BUFFER_RATION_LOWER					75

// Device Speed Checking
#define DVB_PVR_DEVICE_EVENT_CHECK_TICK						10000
// Time Shift
#if 0
#define DVB_PVR_DEVICE_TIME_SHIFT_CHECK_TICK				100
#define DVB_PVR_DEVICE_TIME_SHIFT_REC_BUF_RATIO_THRESHOLD	20
#endif
// Record
#define DVB_PVR_DEVICE_RECORD_CHECK_TICK					500
#define DVB_PVR_DEVICE_RECORD_REC_BUF_RATIO_THRESHOLD		50
#define DVB_PVR_DEVICE_RECORD_THRESHOLD						2
// Playback

EN_PVR_STATUS		_enPVRStatus;
//EN_DEVICE_TYPE	_enPVRDeviceType = EN_CARDREADER_DEVICE;
EN_DEVICE_TYPE		_enPVRDeviceType = EN_USB_DEVICE;
CTOS_SEMAPHORE		PVR_API_Semaphore;
CTOS_TASK			stPVRTask;
u8 					au8PVRTaskStack[DVB_PVR_TASK_STACK_SIZE];
static void 				DVB_PVR_Task(u32 u32Argc, void* pArgv);

CTOS_QUEUE 			stPvrQueue;
u32					u32PvrQueueMsg[PVR_QUEUE_SIZE];
MSG_PARAMETER		stPvrSendMsg;
bool8				_b8SetCacheBitRate = FALSE;

EN_PVR_STATUS		_enCBStatus;
CTOS_TASK			stCBTask;
u8					au8CBTaskStack[DVB_PVR_TASK_CB_STACK_SIZE];
void				DVB_Callback_Task(u32 u32Argc, void* pArgv);
CTOS_QUEUE			stCBQueue;
u32					u32CBQueueMsg[PVR_QUEUE_SIZE];
MSG_PARAMETER		stCBSendMsg;
CTOS_SEMAPHORE		PVR_CB_Semaphore;

#ifdef PVR_FILL_TASK_ENABLE
CTOS_TASK			_stPVRFillTask;
u8					_au8PVRFillTaskStack[DVB_PVR_FILL_TASK_STACK_SIZE];
bool8				_b8PVRFillTaskResume = FALSE;
CTOS_SEMAPHORE		PVR_Fill_Data_Semaphore;
void				DVB_PVR_Fill_Task(u32 u32Argc, void* pArgv);
void				DVB_PVR_Fill_Task_Active(bool8 b8Active);
void 				_dvb_pvr_fill_data_notify(void);
#endif

/*******************************************************************************************/       
#if 1
#define DVBPVR_MSG(p) 		PVR_Printf p
#else
#define DVBPVR_MSG(p)
#endif

#if 1
#define DVBPVR_DBG(p) 		PVR_Printf p
#else
#define DVBPVR_DBG(p)
#endif

//===============================New Params===============================
static DVB_PVR_NOTIFY_FN _fpNotify = NULL;
static u16 _u16ParserAid, _u16ParserVid;
static u16 _u16LiveAid, _u16LiveVid;

/*for recording ticks*/
static bool8 _b8DataOKLastTime = TRUE;
static u32 	_u32RecordingTime = 0;
static u32 	_u32NoDataTimeTotal = 0;
static u32	_u32StartTicks = 0;
static u32	_u32LastTicks = 0;
static u32	_u32LastRecordingDuration = 0;
static u32	_u32SectorSize = 512;

/*for stream rate calculate*/
static u32 _u32LastRecordingTicks = 0;
static u32 _u32CurrentRecordingTicks = 0;
static u32 _u32LastStreamRate = 0;
static u32 _u32CurrentStreamRate = 0;

/*for decoder work checking*/
static u32		_u32FilterCallbackLastCount = 0;
static u32		_u32FilterCallbackInitSpeed = 0;
static u32		_u32FilterCallbackInitSpeedTemp = 0;
static bool8	_b8SpeedInitOnNoService = FALSE;
static bool8	_b8GotFirstFilterCallbackSpeed = FALSE;

// Device Speed Checking
static u32 _u32DeviceEventLastTick = 0;
// Time Shift
#if 0
static bool8 _b8DeviceTimeShiftCheck = FALSE;
static u32 _u32DeviceTimeShiftLastTick = 0;
#endif
// Record
static bool8 _b8DeviceRecordCheck = FALSE;
static u32 _u32DeviceRecordFilterLastCount = 0;
static u32 _u32DeviceRecordFilterCurCount = 0;
static u32 _u32DeviceRecordWriteLastTick = 0;
static u32 _u32DeviceRecordWriteErrorCount = 0;
// Playback

//extern dvb function point struct
static ST_PVR_EXTERN_DVB_FN* _pstFnExternDvb = NULL;

/*******************************************************************************************/
static void DVB_PVR_ResetStreamRateCalc(void)
{
	_u32LastRecordingTicks = 0;
	_u32CurrentRecordingTicks = 0;
	_u32LastStreamRate = 0;
	_u32CurrentStreamRate = 0;
}

/*******************************************************************************************/
static void DVB_PVR_ResetFilterCallbackSpeedCalc(bool8 b8GotFirstFilterCallbackSpeed)
{
	/*for decoder work checking*/
	_b8SpeedInitOnNoService = FALSE;
	_b8GotFirstFilterCallbackSpeed = b8GotFirstFilterCallbackSpeed;
	_u32FilterCallbackLastCount = 0;
	_u32FilterCallbackInitSpeed = 0;
	_u32FilterCallbackInitSpeedTemp = 0;
}

/*******************************************************************************************/
u32 DVB_PVR_GetLastRecordingDuration(void)
{
	return _u32LastRecordingDuration;
}

/*******************************************************************************************/
u32 DVB_PVR_GetCurrentRecordingDuration(void)
{
	return (CT_OS_TimerMinus(CT_OS_TimerMinus(_u32RecordingTime, _u32NoDataTimeTotal),_u32StartTicks) + 1);
}

/*******************************************************************************************/
static void DVB_PVR_SaveLastRecordingDuration(void)
{
	_u32LastRecordingDuration = DVB_PVR_GetCurrentRecordingDuration();
}

/*******************************************************************************************/
void DVB_PVR_ResetRecordingTime(void)
{
	_b8DataOKLastTime = TRUE;
	_u32RecordingTime = 0;
	_u32NoDataTimeTotal = 0;
	CT_OS_MS_GetClock(&_u32StartTicks);
	_u32LastTicks = _u32StartTicks;
}

/*******************************************************************************************/
static bool8 DVB_PVR_IsDecoderWorking(void)
{
	bool8 b8NoService;
	bool8	b8ReturnVal = FALSE;
	u32 u32FilterCallbackCurCount = 0;
	u32	u32FilterCallbackCurSpeed = 0;
	static u8 u8LowSpeed;

	u32FilterCallbackCurCount = PVR_GetFilterCallbackCount();

	if(_u32FilterCallbackInitSpeed == 0)
	{
		//Check no service
		/*
		if(CT_MPG_CheckStreamTSType(EN_STREAM_TYPE_VIDEO) == EN_CT_TS_TYPE_NO_STREAM)
		{
			if(CT_MPG_CheckStreamTSType(EN_STREAM_TYPE_AUDIO) == EN_CT_TS_TYPE_NO_STREAM)
			{
				b8NoService = TRUE;
			}
			else
			{
				b8NoService = FALSE;
			}
		}
		else
		{
			b8NoService = FALSE;
		}
		*/
		b8NoService = FALSE;

		if( b8NoService != _b8SpeedInitOnNoService )
		{
			_b8SpeedInitOnNoService = b8NoService;
			_u32FilterCallbackLastCount = 0;
			//_u32FilterCallbackInitSpeed = 0;
			_u32FilterCallbackInitSpeedTemp = 0;
			//DVBPVR_MSG(("!*<1>Speed[%ld : %ld]\n",u32FilterCallbackCurSpeed,_u32FilterCallbackInitSpeed));
			return TRUE;
		}

		if(u32FilterCallbackCurCount < _u32FilterCallbackLastCount)
		{
			_b8SpeedInitOnNoService = FALSE;
			_u32FilterCallbackLastCount = 0;
			//_u32FilterCallbackInitSpeed = 0;
			_u32FilterCallbackInitSpeedTemp = 0;
		}
		else
		{
			_u32FilterCallbackInitSpeedTemp = u32FilterCallbackCurCount-_u32FilterCallbackLastCount;
			_u32FilterCallbackLastCount = u32FilterCallbackCurCount;
		}
		//DVBPVR_MSG(("!*<2>Speed[%ld : %ld]\n",u32FilterCallbackCurSpeed,_u32FilterCallbackInitSpeed));
		return TRUE;
	}

	if(u32FilterCallbackCurCount < _u32FilterCallbackLastCount)
	{
		//Need recalc the Callback Init Speed
		_b8SpeedInitOnNoService = FALSE;
		_u32FilterCallbackLastCount = 0;
		_u32FilterCallbackInitSpeed = 0;
		_u32FilterCallbackInitSpeedTemp = 0;

		//DVBPVR_MSG(("!*<3>Speed[%ld : %ld]\n",u32FilterCallbackCurSpeed,_u32FilterCallbackInitSpeed));
		return TRUE;
	}

	u32FilterCallbackCurSpeed = u32FilterCallbackCurCount - _u32FilterCallbackLastCount;

	if( u32FilterCallbackCurSpeed == 0 )
	{
		b8ReturnVal = FALSE;
	}
	else
	{
		if( u32FilterCallbackCurSpeed > _u32FilterCallbackInitSpeed )
		{
			if( _b8SpeedInitOnNoService == TRUE )
			{
				if( u32FilterCallbackCurSpeed > _u32FilterCallbackInitSpeed*2 )
				{
					u8LowSpeed = 0;
					b8ReturnVal = TRUE;
				}
				else
				{
					b8ReturnVal = FALSE;
					//DVBPVR_MSG(("!*<a>Speed[%ld : %ld]\n",u32FilterCallbackCurSpeed,_u32FilterCallbackInitSpeed));
				}
			}
			else
			{
				u8LowSpeed = 0;
				b8ReturnVal = TRUE;
			}
		}
		else
		{
			if( _b8SpeedInitOnNoService == TRUE )
			{
				b8ReturnVal = FALSE;
				//DVBPVR_MSG(("!*<b>Speed[%ld : %ld]\n",u32FilterCallbackCurSpeed,_u32FilterCallbackInitSpeed));
			}
			else
			{
				if( u32FilterCallbackCurSpeed < (_u32FilterCallbackInitSpeed/2) )
				{
					u8LowSpeed++;
					if(u8LowSpeed >= 3)
					{
						u8LowSpeed = 3;
						b8ReturnVal = FALSE;
					}
					else
					{
						b8ReturnVal = TRUE;
					}
					//DVBPVR_MSG(("!*<c>Speed[%ld : %ld]\n",u32FilterCallbackCurSpeed,_u32FilterCallbackInitSpeed));
				}
				else
				{
					u8LowSpeed = 0;
					b8ReturnVal = TRUE;
				}
			}// end if( _b8SpeedInitOnNoservice == TRUE )
		}//end if( u32FilterCallbackCurSpeed > _u32FilterCallbackInitSpeed )
	}

	_u32FilterCallbackLastCount = u32FilterCallbackCurCount;
	//DVBPVR_MSG(("!*Speed[%ld : %ld]\n",u32FilterCallbackCurSpeed,_u32FilterCallbackInitSpeed));
	
	return b8ReturnVal;
}

static void DVB_PVR_CalcRecordingTicks(void)
{
	CT_OS_MS_GetClock(&_u32RecordingTime);

	if(DVB_PVR_IsDecoderWorking() == TRUE)
	{
		if(_b8DataOKLastTime == TRUE)
		{
		}
		else
		{
			_u32NoDataTimeTotal += (CT_OS_TimerMinus(_u32RecordingTime, _u32LastTicks)+1);

			_b8DataOKLastTime = TRUE;
		}
	}
	else
	{
		if(_b8DataOKLastTime == TRUE)
		{
			_b8DataOKLastTime = FALSE;
			//_u32NoDataTimeTotal += CT_OS_TimerMinus(_u32RecordingTime, _u32LastTicks);
		}
		else
		{
			_u32NoDataTimeTotal += (CT_OS_TimerMinus(_u32RecordingTime, _u32LastTicks)+1);
		}
	}
	_u32LastTicks = _u32RecordingTime;
}
/*end for recording ticks*/

#define PVR_MACRO_IDLE( )                                     \
{                                                         \
    register u32 dwIdle = 4;                              \
    asm volatile ("udiv %0, %0, %%g0;" : : "r" (dwIdle) );\
}
//EN_PVR_STATUS DVB_PVR_Initial(void)
EN_PVR_STATUS DVB_PVR_Initial(ST_PVR_EXTERN_DVB_FN *pstFn_Extern_Dvb)
{
	EN_CTOS_STATUS	enOsStatus;
	static bool8	b8PVRInitFlag = FALSE;
	_enPVRStatus = EN_PVR_STATUS_SUCCESS;

	if (TRUE == b8PVRInitFlag)
	{
		return _enPVRStatus;
	}

	if(pstFn_Extern_Dvb == NULL)
	{
		_pstFnExternDvb = NULL;
		return EN_PVR_STATUS_FAIL;
	}
	
	_pstFnExternDvb = pstFn_Extern_Dvb;

	// PVR Task
	enOsStatus = CT_OS_CreateTask ( &stPVRTask,
									"PVRTk",
									DVB_PVR_Task,
									&au8PVRTaskStack[0],
									DVB_PVR_TASK_STACK_SIZE,
									DVB_PVR_TASK_PRIORITY,
									DVB_PVR_TASK_TIMESLICE);

	if (EN_CTOS_SUCCESS != enOsStatus)
	{
		_enPVRStatus = EN_PVR_STATUS_FAIL;
		DVBPVR_MSG(("Create PVR Task Fail\n"));
	}

	enOsStatus = CT_OS_CreateMsgQueue(&stPvrQueue, "PVRQ", &u32PvrQueueMsg[0], PVR_QUEUE_SIZE, EN_CTOS_SUSPEND_FIFO);
	if (EN_CTOS_SUCCESS != enOsStatus)
	{
		_enPVRStatus = EN_PVR_STATUS_FAIL;
		DVBPVR_MSG(("Create PVR MessageQ Fail\n"));
	}

	if (EN_CTOS_SUCCESS != CT_OS_CreateSemaphore(&PVR_API_Semaphore, "PVR_Sem", 0, EN_CTOS_SUSPEND_FIFO))
	{
		DVBPVR_MSG(("\n\r PVR_API_WARNING: CT_OS_CreateSemaphore Error"));
	}
	else
	{
		DVBPVR_MSG(("\n\r CREATE SEM OK FOR PVR API\n\r"));
	}

	PVR_InitializeKernel();

	b8PVRInitFlag = TRUE;
	if(_enPVRStatus == EN_PVR_STATUS_SUCCESS)
	{
		CT_OS_ResumeTask(&stPVRTask);
	}

	#ifdef PVR_FILL_TASK_ENABLE
	// PVR Fill Task
	enOsStatus = CT_OS_CreateTask ( &_stPVRFillTask,
									"PVRFill",
									DVB_PVR_Fill_Task,
									&_au8PVRFillTaskStack[0],
									DVB_PVR_FILL_TASK_STACK_SIZE,
									DVB_PVR_FILL_TASK_PRIORITY,
									DVB_PVR_FILL_TASK_TIMESLICE);

	if (EN_CTOS_SUCCESS != enOsStatus)
	{
		_enPVRStatus = EN_PVR_STATUS_FAIL;
		DVBPVR_MSG(("Create PVR Fill Task Fail\n"));
	}

	if (EN_CTOS_SUCCESS != CT_OS_CreateSemaphore(&PVR_Fill_Data_Semaphore, "PVR_FDSem", 0, EN_CTOS_SUSPEND_FIFO))
	{
		DVBPVR_MSG(("\n\r PVR_FillData_WARNING: CT_OS_CreateSemaphore Error"));
	}
	else
	{
		DVBPVR_MSG(("\n\r CREATE SEM OK FOR PVR FillData\n\r"));
	}

	PVR_Register_Fill_Data_Notify(_dvb_pvr_fill_data_notify);
	#endif

	PVR_ResetRecInfo();
	PVR_ResetPlayInfo();
	DVB_PVR_SetSectorSize(512);

	return _enPVRStatus;
}

static void DVB_PVR_Task(u32 u32Argc, void* pArgv)
{
	EN_PVR_TASK_STATE	enPvrTaskState = EN_PVR_TASK_IDLE;
	EN_CTOS_STATUS	    enOsStatus;
	u32				    u32PvrRecvMsgLen;
	MSG_PARAMETER		stPvrRecvMsg;

	EN_PVR_RECORD_STATUS	enRecStatus;

	static u8 u8Count = 0;

⌨️ 快捷键说明

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