📄 pe_consumer_dvd.cpp
字号:
}
}
/* also check the pts if we are not in E_STD active mode */
if (m_E_STD_Active == FALSE)
{
/* this is for the case that avsync is out or we are in slow/pause trick modes */
if ( (time90k_NavPackPTS <= time90k_PTS) && (time90k_PTS < (time90k_NavPackPTS + 900000) ) )
{
DBGPRINT(DBG_ON(DBG_NVPCK), ("NavPackAVSync: USING PTS\n"));
break;
}
}
OS_TaskDelayMsec(20);
}
else
{
/*
* FF/REW Trickmode
*/
ULONG ulNewTickCount = OS_GetTicks();
/* fastfwd/rewind rates are throttled by the navpacks.
* this eliminates difficulties with trying to sync to PTS values in trickmode */
/* if clock rolled over just send this navpack out */
if (ulNewTickCount < ulLastTickCount)
{
DBGPRINT(DBG_ON(DBG_NVPCK), ("NavPackAVSync: clock rolled over\n"));
break;
}
/* determine how much time has passed since the last navpack was sent */
offset = ((ulNewTickCount - ulLastTickCount) / (OS_GetTickRate() / 1000)) * 90;
/* adjust according to playrate - m_playrate.rate must be > PLAY_RATE_NORMAL */
offset *= (m_playrate.rate / PLAY_RATE_NORMAL);
/* if we're in reverse step - just send the navpack */
if ( (m_playrate.rate == PLAY_RATE_STEP) && (m_playrate.direction == PE_ISTREAMCTRL_DIRECTION_BACKWARD) )
{
break;
}
if (m_playrate.direction == PE_ISTREAMCTRL_DIRECTION_FORWARD)
{
/* check the current time info */
if (m_time90k_NavPackPTS + offset >= time90k_NavPackPTS)
{
/* if we are going forward in trick mode look for forward rollover */
if (m_E_STD_Active == TRUE)
{
DBGPRINT(DBG_ON(DBG_NVPCK), ("m_E_STD_Active off in fordward trick mode\n\n\n"));
m_E_STD_Active = FALSE;
m_E_STD_Offset = 0;
m_E_STD_Time = 0;
}
break;
}
}
else
{
/* check the current time info */
if (m_time90k_NavPackPTS < time90k_NavPackPTS + offset)
{
if (m_E_STD_Active == TRUE)
{
/* if the PTS rolls over we have crossed into the next VOB */
DBGPRINT(DBG_ON(DBG_NVPCK), ("m_E_STD_Active off in backward trick mode\n"));
m_E_STD_Active = FALSE;
m_E_STD_Offset = 0;
m_E_STD_Time = 0;
}
break;
}
}
OS_TaskDelayMsec(20);
}
PrevPTSValid = TRUE;
time90k_PrevPTS = time90k_PTS;
}
PrevPTSValid = TRUE;
time90k_PrevPTS = time90k_PTS;
DBGPRINT(DBG_ON(DBG_NVPCK), ("NavPackAVSync - FINISHED - PTS=%ld, STC=%ld\n",
time90k_PTS, time90k_STC));
}
/**
* cPEConsumer_DVD::NavPackTask
*
* @param pvParam
*
* @return PE_STATUS
*/
ULONG cPEConsumer_DVD::NavPackTask(PVOID pvParam)
{
DEMUXOUTPUTMESSAGE *pMessage = NULL;
cPayload *pPayload1 = NULL;
cPayload *pPayload2 = NULL;
BOOLEAN fVideoExists = FALSE;
TIME90k time90k_NavPackPTS = 0;
BOOLEAN ESTD_GetOffset = 0;
BYTE *buf = NULL;
ULONG ulNavPckID;
PE_NVPCK_EVENT_INFO info;
TIME45k time45k_CurrSTC;
TIME45k time45k_CurrPTS;
PE_STATUS status;
if (pvParam == NULL)
{
OS_TaskExit();
return (PE_FAILURE);
}
/* setup E_STD Values */
m_E_STD_Offset = 0;
m_E_STD_StartPTM = 0;
m_E_STD_EndPTM = 0;
m_E_STD_Time = 0;
m_E_STD_RolledOver = FALSE;
m_E_STD_Active = FALSE;
m_LastSPUTargetPTS = 0;
m_LastTickCount = 0;
m_fFlushNavPacks = FALSE;
ulNavPckID = 0;
m_NvPckSyncState = PE_NVPCK_SYNC_FIRST;
/* Sit and spin forever */
while (1)
{
/* reset the navpack payload pointers */
if (pPayload1 != NULL)
{
delete pPayload1;
pPayload1 = NULL;
}
if (pPayload2 != NULL)
{
delete pPayload2;
pPayload2 = NULL;
}
/* if it hasn't been done yet release the previous navpack message */
if (pMessage != NULL)
{
if (pMessage->payload != NULL)
{
/* release the payload */
delete (pMessage->payload);
}
/* if notification of message done is requested give it now */
if (pMessage->semMsgDone)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("NavPackTask: notification of message done\n"));
OS_SemGive(pMessage->semMsgDone);
}
/* Do end of stream processing */
if (pMessage->EndOfStream == TRUE)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("NavPackTask: notification of end of stream\n"));
/* if this is the last VOBU of a cell with VOBU Stills then we need
* to block until the still has been released */
if (pMessage->fIsVobuStill == TRUE)
{
while (m_fPauseAfterVOBU == TRUE)
{
OS_TaskDelayMsec(100);
if (m_fAbort == TRUE)
{
m_fPauseAfterVOBU = FALSE;
break;
}
}
}
/* call base class for end of stream processing */
cPEConsumer::ProcessEndOfStream(pMessage->StreamContext);
}
/* release the message */
m_pNvPckStream->ReleaseMsg(pMessage);
pMessage = NULL;
}
/* Get a navpack stream message */
pMessage = (DEMUXOUTPUTMESSAGE*)m_pNvPckStream->Read(OS_WAIT_FOREVER);
if (NULL == pMessage)
{
OS_TaskYield();
continue;
}
/* check for an info packet */
if (pMessage->fInfoPayload == TRUE)
{
/* ignore info packets */
continue;
}
/* check for termination message */
if (pMessage->fTerminate == TRUE)
{
DbgPrint(("\n>>>> NavPackTask TERMINATION MESSAGE <<<<\n\n"));
goto navpack_task_exit;
}
/* Handle DiscontinuityAtBeginning messages */
if (TRUE == pMessage->DiscontinuityAtBeginning)
{
DBGPRINT(DBG_ON(DBG_NVPCK), ("NavPackTask: DiscontinuityAtBeginning\n"));
}
/* complete flush on stop notification */
if (TRUE == pMessage->fStopNotification)
{
DBGPRINT(DBG_ON(DBG_NVPCK), ("NavPackTask: fStopNotification\n"));
m_fFlushNavPacks = FALSE;
m_E_STD_Active = FALSE;
/* reset times */
ESTD_GetOffset = FALSE;
m_E_STD_Active = FALSE;
m_E_STD_Offset = 0;
m_E_STD_Time = 0;
m_E_STD_RolledOver = FALSE;
m_time90k_NavPackPTS = 0;
m_LastPTS = 0;
m_NvPckSyncState = PE_NVPCK_SYNC_FIRST;
}
if (NULL != pMessage->payload)
{
int n;
TIME90k time90k_VOBU_S_PTM;
TCH_PAYLOAD(pMessage->payload);
status = PE_SUCCESS;
/* Nav packets will always come in pairs since they reside in the same sector and we read a
* sector at a time. The first packet will be a PCI packet followed by the DSI packet. */
/* record current navpack ID */
m_ulNavPckID = pMessage->ulVobuCC;
/* make a reference for the pci packet */
while (1)
{
pPayload1 = pMessage->payload->REF_PAYLOAD;
if (pPayload1 != NULL)
{
break;
}
OS_TaskYield();
}
pPayload1->set_wr_ptr((PVOID)((ULONG)(pPayload1->get_rd_ptr()) + 986));
/* make a reference for the dsi packet */
while (1)
{
pPayload2 = pMessage->payload->REF_PAYLOAD;
if (pPayload2 != NULL)
{
break;
}
OS_TaskYield();
}
pPayload2->set_rd_ptr((PVOID)((ULONG)(pPayload2->get_rd_ptr()) + 986));
/* release the payload */
delete (pMessage->payload);
pMessage->payload = NULL;
/* validate the PCI packet header */
buf = (BYTE*)pPayload1->get_rd_ptr();
for (n = 0; n < 7; n++)
{
if (buf[n] != PCI_STRT[n])
{
DbgPrint(("%s, %d: PCI Invalid!\n", __FILE__, __LINE__));
status = PE_FAILURE;
break;
}
}
/* get the vobu_start_ptm */
time90k_VOBU_S_PTM = MAKE_DWORD(&buf[19]);
/* if we are in estd, then the next navpack will give us the
* start ptm of the next vobu so we can find the STC delta */
if (ESTD_GetOffset == TRUE)
{
ESTD_GetOffset = FALSE;
m_E_STD_StartPTM = MAKE_DWORD(buf + 19);
m_E_STD_Offset = m_E_STD_EndPTM - m_E_STD_StartPTM;
m_E_STD_Active = TRUE;
DBGPRINT(DBG_ON(DBG_NVPCK), ("ESTD ACTIVE offset %d, estd active %d, start time %d\n\n", m_E_STD_Offset, m_E_STD_Active, m_E_STD_StartPTM));
}
/* validate the DSI packet header */
buf = (BYTE*)pPayload2->get_rd_ptr();
for (n = 0; n < 7; n++)
{
if (buf[n] != DSI_STRT[n])
{
DbgPrint(("%s, %d: DSI Invalid!\n", __FILE__, __LINE__));
status = PE_FAILURE;
break;
}
}
/* get the nav pack pts (navpack scr from the DSI) */
/* elm: OR, use the VOBU_S_PTM if it's less than the navpack scr. This *should* never happen, but it does */
time90k_NavPackPTS = MIN(MAKE_DWORD(&buf[7]), time90k_VOBU_S_PTM);
/* check if video exists in the vobu...
* In Blue Book Part 3 is states VOBU_1STREF_EA will equal 0 if there is no video data present */
fVideoExists = (MAKE_DWORD(&buf[19]) == 0) ? FALSE : TRUE;
#if DBG_ON(DBG_NVPCK)
DBGPRINT((fVideoExists == FALSE), ("****** NavPackTask: VIDEO DATA DOES NOT EXIST ******\n"));
#endif
}
else
{
status = PE_FAILURE;
}
if (PE_SUCCESS == status)
{
#ifndef __DISABLE_SYNC
/* syncronize to the video stream */
if (time90k_NavPackPTS != 0xffffffff)
{
NavPackAVSync(time90k_NavPackPTS, m_LastTickCount, fVideoExists);
}
#endif
/* update navpck synch state */
m_NvPckSyncState = (m_NvPckSyncState == PE_NVPCK_SYNC_FIRST) ? PE_NVPCK_SYNC_SECOND : PE_NVPCK_SYNC_NORMAL;
/* send the navpack off to the navigator */
if (m_fFlushNavPacks == FALSE)
{
/* send the navpack to the nav */
info.pPCIpayload = pPayload1->get_rd_ptr();
info.pDSIpayload = pPayload2->get_rd_ptr();
status = SendEvent(PE_EVENT_NVPCK, &info);
/* update the PTS */
if (GetVidPTS(&time45k_CurrPTS, &time45k_CurrSTC) != PE_SUCCESS)
{
DbgPrint(("NavPackTask: Failed to get video pts\n"));
}
/* take a sem and update the member times related to navpacks */
OS_SemTake(m_semNavPackState, OS_WAIT_FOREVER);
m_time90k_NavPackPTS = time90k_NavPackPTS;
m_LastPTS = time45k_CurrPTS * 2;
m_LastTickCount = OS_GetTicks();
OS_SemGive(m_semNavPackState);
/* if the nav pack triggers an E_STD_active condition
* set a flag for it, otherwise clear it */
if (status == PE_EVNT_E_STD_ACTIVE)
{
/* get the end ptm of this packet */
buf = (BYTE*)pPayload1->get_rd_ptr();
m_E_STD_EndPTM = MAKE_DWORD(buf + 23);
/* get the offset on the next navpack, and turn on ESTD active */
ESTD_GetOffset = TRUE;
}
}
else
{
DBGPRINT(DBG_ON(DBG_NVPCK), ("PENavPackTask: m_fFlushNavPacks!
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -