📄 dr_prefetch_bdrom.cpp
字号:
delete pStreamPayload;
pStreamPayload = NULL;
/* reset flags */
streamMessage.DataDiscontinuity = FALSE;
/* set the LocalContext */
if (stream_status == DR_SUCCESS)
{
lPayloadsSent++;
streamMessage.LocalContext = (PVOID)m_lcManager.NewLocalContext();
m_clpInfo.ClpInfoGet_ClipNum(&((LocalContext*)(streamMessage.LocalContext))->ulClipNum);
((LocalContext*)(streamMessage.LocalContext))->pvContext = pvContext;
((LocalContext*)(streamMessage.LocalContext))->spnOfPayload = (ULONG)(boCurrentPosition / BD_TSPACKETSIZE);
}
} while ((boCurrentPosition < boLast) && (boCurrentPosition >= boFirst) && (fLoaderError == FALSE));
errout:
if (pStreamPayload != NULL)
{
delete pStreamPayload;
pStreamPayload = NULL;
}
if (fGotDevSem == TRUE)
{
DBGPRINT(DBG_ON(DEBUG_DEVSEM), ("EXIT - SEM GIVE %u!!\n", m_idnum));
OS_SemGive(m_semDevice);
}
if (fLoaderError == TRUE)
{
lPayloadsSent *= -1;
}
return (lPayloadsSent);
}
DR_ERROR DRPrefetch_BDROM::drSendSubtextInfo(UBYTE numFiles, UBYTE *font_names, ULONG tIn, PVOID pvContext)
{
ULONG ulPayloadSize;
DROUTPUTMESSAGE streamMessage;
cPayload *pStreamPayload = NULL;
BYTE *wrPtr;
INFOPAYLOAD *infoPayload;
ULONG ulBytesToWrite;
/* these are used */
streamMessage.fInfoPayload = TRUE;
streamMessage.StreamContext = pvContext;
/* Get a buffer from the stream */
pStreamPayload = drGetPayload();
if (pStreamPayload == NULL)
{
return (DR_FAILURE);
}
/* check that the font list can fit into a single payload (shouldn't fail unless the payloads are made super-small) */
ulPayloadSize = (ULONG)((pStreamPayload->get_max_size()));
ulBytesToWrite = ((ULONG)numFiles * 5) + 1 + sizeof(ULONG);
DbgAssert(ulPayloadSize >= ulBytesToWrite);
/* get the payload's write pointer */
infoPayload = (INFOPAYLOAD*)pStreamPayload->get_base_ptr();
/* set the type */
infoPayload->bType = INFOTYPE_FONTLIST;
/* set the data pointer */
wrPtr = infoPayload->data_packet.data;
/* write to the payload */
wrPtr[0] = numFiles; /* the number of font files */
memcpy(&wrPtr[1], font_names, numFiles * 5); /* copy in the font names */
memcpy(&wrPtr[ulBytesToWrite - sizeof(ULONG)], &tIn, sizeof(ULONG)); /* copy in a ULONG for time */
/* Set the size of the data */
infoPayload->data_packet.size = ulBytesToWrite;
/* transfer the payload to the PE */
drSendStream(streamMessage, pStreamPayload);
/* delete the payload */
delete pStreamPayload;
pStreamPayload = NULL;
return(DR_SUCCESS);
}
/**
* StopAtChangePoint - stop at next change point
*
* @param fAngle - look for angle change point or just end of current I-frame
* @param ulAngleChangePointPTS - the PTS of the angle change point found
*
* @retval DR_FAILURE if no angle change point was found (ulAngleChangePointPTS is useless)
* DR_SUCCESS an angle change point was successfully found
*
* @remarks none.
*/
DR_ERROR DRPrefetch_BDROM::StopAtChangePoint(BOOLEAN fAngle, ULONG *ulAngleChangePointPTS, PVOID *ret_pvContext)
{
DR_ERROR status = DR_SUCCESS;;
ULONG spnOut = 0;
ULONG ciAnglePoint;
ULONG fiAnglePoint;
ULONG ulBufferLevel;
ULONG spnIn;
ULONG ptsOut;
PVOID pvContext = NULL;
ULONG ulClipNum;
BOOLEAN fPlayQueueWasEnabled;
PLAYCMD play;
CLIPINFO_db *pClipInfo = NULL;
DBGPRINT(DBG_ON(DBG_TRACE), ("\nStopAtChangePoint:\n"));
/* Abort() also clears and disables the queue */
fPlayQueueWasEnabled = Abort();
m_clpInfo.ClpInfoGet_ClipNum(&ulClipNum);
/* Get clipinfo of loaded clip */
m_clpInfo.ClpInfoGet_ClipInfo(&pClipInfo);
/*
* Calculate the level to drain the buffer down to. This level should
* be the minimum amount of data needed to guarantee seamless playback of data
* during the angle change.
*/
ulBufferLevel = (ULONG)((BD_TJUMP_ANGLE_MAX) * 192 / 188 * pClipInfo->TS_recording_rate) + 1;
/*
* @TODO: Account for buffering in the decoder.
*/
/* Determine how many payloads are needed for this buffer level */
ulBufferLevel = (ulBufferLevel / (PAYLOAD_SIZE * 1024) ) + 1;
/* Drain buffer down to calculated level */
if (FALSE == Flush(TRUE, ulBufferLevel, ulClipNum, &spnIn, &pvContext) )
{
return(DR_FAILURE);
}
if (pvContext == NULL)
{
LocalContext *lcTemp;
lcTemp = m_lcManager.CurrentLocalContext();
spnIn = lcTemp->spnOfPayload;
pvContext = lcTemp->pvContext;
}
DBGPRINT(DBG_ON(DBG_TRACE), ("spnIn: 0x%x\n", spnIn));
/* if we're in a discrete mode, don't worry about an angle change point - just change at the next i-frame */
if (m_BDspeed.fReverse || m_BDspeed.bDiscrete)
{
fAngle = FALSE;
}
/* find an angle change point to read up to */
if ( CLPINFO_SUCCESS != m_clpInfo.ClpInfoSearch_ChangePoint(fAngle, m_BDspeed.fReverse, spnIn, &spnOut, &ptsOut, &ciAnglePoint, &fiAnglePoint) )
{
/* no change point found */
DBGPRINT(DBG_ON(DBG_TRACE), ("StopAtChangePoint FAILED\n"));
status = DR_FAILURE;
spnOut = m_clpInfo.ClpInfoGet_spnLast(); /* play what's left of the playitem */
play.bdrom.playFlag = PLAYFLAG_SPNEOF;
}
else
{ /* change point found */
play.bdrom.playFlag = PLAYFLAG_SPN;
}
DBGPRINT(DBG_ON(DBG_TRACE), ("\nptsOut: 0x%x\n", ptsOut));
DBGPRINT(DBG_ON(DBG_TRACE), ("spnOut: 0x%x\n\n", spnOut));
if (spnOut != spnIn)
{
/* PLAY THE "small" PLAY CHUNK */
QueueControl(DR_QUEUE_CMD_ENABLE);
play.bdrom.strmType = DR_STREAM_MAIN;
play.bdrom.fReverse = 0;
play.bdrom.bDiscrete = 0;
play.bdrom.playItem_id = 0;
play.bdrom.playList_id = 0;
play.bdrom.title_num = 0;
play.bdrom.ulFilenum = ulClipNum;
play.bdrom.spnIn = spnIn;
play.bdrom.spnOut = spnOut;
play.bdrom.ubRefToSTC = 0; /* not needed for spn playback */
play.bdrom.connectCond = VDVD_CONNECTION_6;
play.bdrom.pvContext = pvContext;
Play(play, TRUE); /* Blocks until play command has been received */
/* return the playqueue to the original state */
if(fPlayQueueWasEnabled == TRUE)
{
QueueControl(DR_QUEUE_CMD_ENABLE);
}
else
{
QueueControl(DR_QUEUE_CMD_DISABLE);
}
}
*ulAngleChangePointPTS = ptsOut;
*ret_pvContext = pvContext;
return(status);
}
/**
* GetPlayRate - return the play rate
*
* @param none
*
* @retval the play rate as a field of two 16-bit values.
*
* @remarks none.
*/
uint32 DRPrefetch_BDROM::GetPlayRate(void)
{
return((m_BDspeed.fReverse << 8) | m_BDspeed.bDiscrete);
}
/**
* GetContext - return the current context
*
* @param none
*
* @retval the context.
*
* @remarks none.
*/
PVOID DRPrefetch_BDROM::GetContext(void)
{
return(m_pvPlayContext);
}
/**
* GetNextContext - return the next context
*
* @param none
*
* @retval the context if it exists, NULL otherwise
*
* @remarks Queue must be disabled before this call!
*/
PVOID DRPrefetch_BDROM::GetNextContext(void)
{
PLAYMSG *pInputMessage = NULL;
PVOID pvContext = NULL;
pInputMessage = (PLAYMSG*)m_prefetchPlayQueue->Read(OS_NO_WAIT);
if (pInputMessage != NULL)
{
/* if there's something in the queue, record its context */
pvContext = pInputMessage->play.bdrom.pvContext;
/* now put the message back into the queue */
m_prefetchPlayQueue->Write((PVOID)pInputMessage, OS_WAIT_FOREVER);
}
return (pvContext);
}
#ifdef DRM_BDPLUS_SUPPORT
/**
* drGetAndSendFixup - Get fixups for the current play item. Send the info to PE.
*
* @param clpInfo - the current clpInfo object
* @param boCurrentPosition - the current byte offset
* @param ulbytesRead - the size of the data
*
* @retval DR_ERROR
*
* @remarks none.
*
*/
DR_ERROR DRPrefetch_BDROM::drGetAndSendFixup(ClpInfo* clpInfo, ULONGLONG boCurrentPosition, ULONG ulbytesRead)
{
/*
* TODO: Compute BD+ fixup table and send to PE
*/
/* NOT IMPLEMENTED */
DbgPrint(("%s:%d - NO DRM_BDPLUS_SUPPORT\n", __FILE__, __LINE__));
return (DR_FAILURE);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -