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