📄 dr_prefetch_bdrom.cpp
字号:
{
/*
* TODO: call DRM lib to get the key for the current play item
*/
status = DR_FAILURE;
DbgPrint(("%s:%d - NO DRM SUPPORT\n", __FILE__, __LINE__));
/* send the key to the PE */
if (status == DR_SUCCESS)
{
INFOPAYLOAD *infoPayload;
infoPayload = (INFOPAYLOAD*)pStreamPayload->get_base_ptr();
infoPayload->bType = INFOTYPE_CRYPTKEY;
/*
* TODO: put the key info into the payload
*/
/* infoPayload->data_packet.data = key for the playitem (might be a handle etc) */
/* infoPayload->data_packet.size = size of the key or key handle being passed */
/* transfer the payload to the PE */
if (drSendStream(streamMessage, pStreamPayload) != DR_SUCCESS)
{
status = DR_FAILURE;
}
}
/* delete the payload */
delete pStreamPayload;
}
/* Done getting the key */
DBGPRINT(DBG_ON(DBG_TRACE), ("DRCommandProc: DR_KEY -- Done getting key\n"));
return (status);
}
#endif
/**
* GetAndSend - gets data from the file and sends it to the output stream
*
* @param fileHandle - the file handle to get data from
* @param inbyte - the start byte to read from
* @param outbyte - the end byte to read to
*
* @retval none
*
* @remarks none.
*/
LONG DRPrefetch_BDROM::GetAndSend(LOADER_FILE_HANDLE hFileHandle, ULONGLONG boFirst, ULONGLONG boLast, BOOLEAN fDataDiscontinuity, BOOLEAN fTrickPlay, PVOID pvContext)
{
BOOLEAN fReadOk = FALSE;
ULONGLONG ullBytesLeft = 0; /* bytes left to read from this playitem */
ULONG ulBytesToRead = 0; /* bytes to read on this loop through */
ULONG ulBytesToRead_ret = 0; /* bytes read on this loop through (only different if error) */
ULONG ulReadSize = 0; /* bytes read on this loop through (only different if error) */
ULONGLONG boCurrentPosition;
ULONG ulPayloadSize;
cPayload *pStreamPayload = NULL;
DROUTPUTMESSAGE streamMessage;
LOADER_ERR ldrStatus;
DR_ERROR stream_status = DR_SUCCESS;
CLIPINFO_db *pClipInfo = NULL;
BOOLEAN fGotDevSem = FALSE;
USHORT usLoopMax;
USHORT usLoopCount = 0;
BOOLEAN fRecheck;
ULONG ulBufferLevel;
BOOLEAN fLoaderError = FALSE;
LONG lPayloadsSent = 0;
/* Get clipinfo of loaded clip */
m_clpInfo.ClpInfoGet_ClipInfo(&pClipInfo);
ulBufferLevel = (ULONG)((BD_TJUMP_BSS_MAX) * 192 / 188 * pClipInfo->TS_recording_rate) + 1;
usLoopMax = (USHORT)((ulBufferLevel / (PAYLOAD_SIZE * 1024) ) + 5);
/* initialize stream flags */
streamMessage.DataDiscontinuity = fDataDiscontinuity;
streamMessage.StreamContext = pvContext;
streamMessage.TimeDiscontinuity = FALSE; /* TODO: use this flag */
#ifdef DRM_SUPPORT
ULONGLONG boFirstRounded = (boFirst / AU_SIZE) * AU_SIZE;
ULONGLONG offset = boFirst - boFirstRounded;
boFirst = boFirstRounded;
#endif
/* everyone takes the semaphore before the loader seek (so there's only one seek at a time) */
OS_SemTake(m_semDevice, OS_WAIT_FOREVER);
DBGPRINT(DBG_ON(DEBUG_DEVSEM), ("START - SEM TAKE %u!!\n", m_idnum));
fGotDevSem = TRUE;
/* seek to the starting point */
if (LOADER_SUCCESS != LoaderFileSeek(m_loader, hFileHandle, LOADER_SEEK_SET, boFirst) )
{
DBGPRINT(DBG_ON(DBG_ERROR), ("dataRetrieve() -- Error Seeking in File\n"));
goto errout;
}
/* start at the beginning */
boCurrentPosition = boFirst;
#ifdef DRM_SUPPORT
DBGPRINT(DBG_ON(DBG_TRACE), ("DR_PLAY -- boFirst=%llu, boFirstRounded=%llu, boLast=%llu\n", boFirst, boFirst-offset, boLast));
#endif
/* set the LocalContext */
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);
/* up to (but not including) the boLast byte of the read */
do
{
/* if we should stop, then stop before we get a payload */
if (m_fAbort == TRUE)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("%s():%u -- abort\n", __FUNCTION__, __LINE__));
break;
}
/* Get a buffer from the stream */
pStreamPayload = drGetPayload();
if (pStreamPayload == NULL)
{
break;
}
#ifdef DRM_SUPPORT
if (offset != 0)
{
pStreamPayload->set_rd_ptr((BYTE*)pStreamPayload->get_rd_ptr() + offset);
offset = 0;
}
#endif
/* how many bytes remain? */
ullBytesLeft = (boLast - boCurrentPosition);
/* how big is each payload? */
ulPayloadSize = (ULONG)((pStreamPayload->get_max_size()));
/* if the payload is bigger than what's left, get all the remaining data */
if (ulPayloadSize > ullBytesLeft)
{
DBGPRINT(DBG_ON(DBG_VERBOSE), ("%s() -- ulBytesLeft=%llu, ulBytesToRead=%d\n", __FUNCTION__, ullBytesLeft, ulBytesToRead));
ulBytesToRead = (ULONG)(ullBytesLeft);
#define MASK 0x7ff
ulReadSize = ulBytesToRead;
if (ulReadSize & MASK)
{
ulReadSize += MASK;
ulReadSize &= ~MASK;
DBGPRINT(DBG_ON(DBG_VERBOSE), ("%s() -- ulBytesLeft=%llu, ulReadSize=%d\n", __FUNCTION__, ullBytesLeft, ulReadSize));
}
}
else
{
ulBytesToRead = ulPayloadSize; /* otherwise, just get as much as we can */
ulReadSize = ulBytesToRead;
}
/* set the payload's user data to the start position */
pStreamPayload->set_user_data( (ULONG)(boCurrentPosition) );
/* This should never happen */
if (boCurrentPosition % BD_TSPACKETSIZE != 0)
{
DbgPrint(("\n\nROUNDING ERROR!!!!\n"));
DbgPrint(("boCurrentPosition: %llu\n\n", boCurrentPosition));
}
/* take care of the device semaphore */
fRecheck = TRUE;
do
{
if (fGotDevSem == TRUE)
{
if ( (m_prefetchStream->EmptyStatus() == 0) || (usLoopCount == usLoopMax) )
{
fGotDevSem = FALSE;
DBGPRINT(DBG_ON(DEBUG_DEVSEM), ("SEM GIVE %u!!\n", m_idnum));
OS_SemGive(m_semDevice);
OS_TaskDelayMsec(20);
}
else
{
fRecheck = FALSE;
}
}
if (fGotDevSem == FALSE)
{
OS_SemTake(m_semDevice, OS_WAIT_FOREVER);
DBGPRINT(DBG_ON(DEBUG_DEVSEM), ("SEM TAKE %u!!\n", m_idnum));
fGotDevSem = TRUE;
usLoopCount = 0;
}
}
while( (fRecheck == TRUE) && (m_fAbort == FALSE) );
if (m_fAbort == TRUE)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("%s():%u -- abort\n", __FUNCTION__, __LINE__));
break;
}
/* to get here you must have the device semaphore */
usLoopCount++;
/* do the read */
ldrStatus = LoaderFileRead(m_loader, hFileHandle, (BYTE*)pStreamPayload->get_wr_ptr(), ulReadSize, &ulBytesToRead_ret);
switch (ldrStatus)
{
case LOADER_SUCCESS: /* loader reports data retrieved successfully */
boCurrentPosition += ulBytesToRead_ret;
fReadOk = TRUE;
/* check that the returned size of the read is the same as we asked for */
if (ulBytesToRead > ulBytesToRead_ret)
{
/* Occurs when the end of file is reached during the read */
DbgPrint(("\n\nLoaderFileRead: incorrect amount of data read. UNEXPECTED EOF LIKELY - ERROR!\n\n"));
DbgPrint(("ulBytesToRead: %u\n", ulBytesToRead));
DbgPrint(("ulBytesToRead_ret: %u\n", ulBytesToRead_ret));
if (m_event != NULL)
{
m_event(m_pContext, DR_EVENT_ERROR, NULL); /* send event */
}
}
/* check that the read begins with good data (transport stream start code) */
if (((BYTE*)(pStreamPayload->get_wr_ptr()))[4] != 0x47)
{
fReadOk = FALSE;
fLoaderError = TRUE;
DbgPrint(("\nLoaderFileRead: bad data read from disk.\n\n"));
if (m_event != NULL)
{
m_event(m_pContext, DR_EVENT_ERROR, NULL); /* send event */
}
}
break;
case LOADER_NULL_PTR: /* something is configured wrong. Abort without sending */
case LOADER_FILE_EOF: /* occurs when EOF flag is already set before we begin reading. Abort without sending */
DbgPrint(("\n\nDR: LoaderFileRead Error: %i\n", ldrStatus));
if (m_event != NULL)
{
m_event(m_pContext, DR_EVENT_ERROR, NULL); /* send event */
}
/* don't report loader error - just want to stop playing right here */
boCurrentPosition = boLast;
fReadOk = FALSE;
break;
case LOADER_FILE_ERROR: /* generalized file error - might just be bad sector. jump ahead and try again (but don't send current) */
default:
DbgPrint(("\n\nDR: LoaderFileRead Error, byte offset = %llu\n", boCurrentPosition));
if (m_event != NULL)
{
m_event(m_pContext, DR_EVENT_ERROR, NULL); /* send event */
}
/* @todo : instead - jump forward to next I-frame */
boCurrentPosition += ulBytesToRead; /* jump ahead to whatever we should have read */
if (LOADER_SUCCESS != LoaderFileSeek(m_loader, hFileHandle, LOADER_SEEK_SET, boCurrentPosition) )
{
DBGPRINT(DBG_ON(DBG_ERROR), ("dataRetrieve() -- Error Seeking in File\n"));
goto errout;
}
fLoaderError = TRUE;
fReadOk = FALSE; /* but don't send it */
break;
}
if (m_fAbort == TRUE)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("%s():%u -- abort\n", __FUNCTION__, __LINE__));
break;
}
/* Update the write pointer */
if (TRUE == fReadOk)
{
pStreamPayload->add_data(ulBytesToRead);
}
/* send the EndOfStream flag */
if ( ( (boCurrentPosition >= boLast) || /* playing fwd reached end of sectors */
(boCurrentPosition < boFirst) ) ) /* playing rev reached beg of sectors */
{
if (fTrickPlay)
{
streamMessage.SequenceEnd = TRUE;
}
}
#ifdef DRM_BDPLUS_SUPPORT
/*
* TODO: If BD+ is running compute the fixup table and send it to the PE
* drGetAndSendFixup(&m_clpInfo, boCurrentPosition, ulBytesToRead);
*/
DbgPrint(("%s:%d - NO DRM_BDPLUS_SUPPORT\n", __FILE__, __LINE__));
#endif
/* transfer the payload to the PE */
stream_status = drSendStream(streamMessage, pStreamPayload);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -