📄 dr_prefetch_bdrom.cpp
字号:
ULONGLONG boStart_of_read;
ULONGLONG boEnd_of_read;
ULONGLONG boNext_fine;
LONG fiLoopHigh;
LONG fiLoopLow;
BOOLEAN fReverse = m_BDspeed.fReverse;
BYTE bDiscrete = m_BDspeed.bDiscrete;
BYTE bApp2loop;
DBGPRINT(DBG_ON(DBG_TRACE), ("DR: TRICK PLAY Begin!\n"));
DBGPRINT(DBG_ON(DBG_TRACE), (" discrete: %u\n", bDiscrete));
DBGPRINT(DBG_ON(DBG_TRACE), (" reverse: %u\n", fReverse));
fDataDiscontinuity = TRUE;
/* Get the EP Coarse */
if ( CLPINFO_SUCCESS != m_clpInfo.ClpInfoGet_EPMapCoarse(EPMAP_STREAMINDEX, &pClpInfoEpMapCoarse, &ulNumCoarseEntries) )
{
DBGPRINT(DBG_ON(DBG_ERROR), (" ClpInfoGet_EPMapCoarse Failed"));
status = FAILURE;
goto out;
}
/* Get the EP Fine */
if ( CLPINFO_SUCCESS != m_clpInfo.ClpInfoGet_EPMapFine(EPMAP_STREAMINDEX, &pClpInfoEpMapFine, &ulNumFineEntries) )
{
DBGPRINT(DBG_ON(DBG_ERROR), (" ClpInfoGet_EPMapFine Failed"));
status = FAILURE;
goto out;
}
/* based on the INtime and OUTtime that were passed into the clpinfodb, get the edges of the EPmap */
ciTrickLow = m_clpInfo.ClpInfoGet_ciStart();
ciTrickHigh = m_clpInfo.ClpInfoGet_ciEnd();
fiTrickLow = m_clpInfo.ClpInfoGet_fiStart();
fiTrickHigh = m_clpInfo.ClpInfoGet_fiEnd();
ciTrickStart = (!fReverse) ? ciTrickLow : ciTrickHigh;
ciTrickEnd = (!fReverse) ? ciTrickHigh : ciTrickLow;
fiTrickStart = (!fReverse) ? fiTrickLow : fiTrickHigh;
fiTrickEnd = (!fReverse) ? fiTrickHigh : fiTrickLow;
increment = (!fReverse) ? 1 : -1;
DBGPRINT(DBG_ON(DBG_TRACE), ("\nciTrickStart: %u\n", ciTrickStart));
DBGPRINT(DBG_ON(DBG_TRACE), ("ciTrickEnd: %u\n", ciTrickEnd));
DBGPRINT(DBG_ON(DBG_TRACE), ("fiTrickStart: %u\n", fiTrickStart));
DBGPRINT(DBG_ON(DBG_TRACE), ("fiTrickEnd: %u\n", fiTrickEnd));
/* sanity checks for trick start and end */
DbgAssert( (fiTrickStart >= pClpInfoEpMapCoarse[ciTrickStart].ref_to_EP_fine_id) || (fiTrickStart < ( (ciTrickStart+1 != ulNumCoarseEntries) ? pClpInfoEpMapCoarse[ciTrickStart+1].ref_to_EP_fine_id : ulNumFineEntries) ) );
DbgAssert( (fiTrickEnd >= pClpInfoEpMapCoarse[ciTrickEnd].ref_to_EP_fine_id) || (fiTrickEnd < ( (ciTrickEnd+1 != ulNumCoarseEntries) ? pClpInfoEpMapCoarse[ciTrickEnd+1 ].ref_to_EP_fine_id : ulNumFineEntries) ) );
/* Trick Loop */
LONG ci = ciTrickStart;
LONG fi = fiTrickStart;
while ( (!fReverse && (ci <= (LONG)ciTrickEnd) && (fi <= (LONG)fiTrickEnd) ) ||
( fReverse && (ci >= (LONG)ciTrickEnd) && (fi >= (LONG)fiTrickEnd) ) )
{
/* find last fi of loop */
/* forward movement */
if ((ci + 1) >= (LONG)ulNumCoarseEntries)
{
fiLoopHigh = ulNumFineEntries;
}
else
{
fiLoopHigh = pClpInfoEpMapCoarse[ci+1].ref_to_EP_fine_id;
}
/* reverse movement */
fiLoopLow = pClpInfoEpMapCoarse[ci].ref_to_EP_fine_id - 1;
DBGPRINT(DBG_ON(DBG_VERBOSE), ("\nci: %u\n", ci));
DBGPRINT(DBG_ON(DBG_VERBOSE), ("fiLoopHigh: %i\n", fiLoopHigh));
DBGPRINT(DBG_ON(DBG_VERBOSE), ("fiLoopLow: %i\n", fiLoopLow));
/* loop till that fi */
while ( (!fReverse && (fi < fiLoopHigh) && (fi <= (LONG)fiTrickEnd) ) ||
( fReverse && (fi > fiLoopLow) && (fi >= (LONG)fiTrickEnd) ) )
{
//DbgAssert((ci+1 < ulNumCoarseEntries) ? fi < pClpInfoEpMapCoarse[ci+1].ref_to_EP_fine_id : 1);
//DbgAssert(fi >= pClpInfoEpMapCoarse[ci].ref_to_EP_fine_id);
DBGPRINT(DBG_ON(DBG_VERBOSE), ("fi: %u\n", fi));
spnCurr = ( (pClpInfoEpMapCoarse[ci].SPN_EP_coarse & 0xfffe0000) | pClpInfoEpMapFine[fi].SPN_EP_fine);
if (fi+1 >= (LONG)fiLoopHigh)
{
if (fi+1 > (LONG)fiTrickHigh)
{
spnNext = (ULONG)(boLast / BD_TSPACKETSIZE);
}
else
{
spnNext = ( (pClpInfoEpMapCoarse[ci+1].SPN_EP_coarse & 0xfffe0000) | pClpInfoEpMapFine[fi+1].SPN_EP_fine);
}
}
else
{
spnNext = ( (pClpInfoEpMapCoarse[ci].SPN_EP_coarse & 0xfffe0000) | pClpInfoEpMapFine[fi+1].SPN_EP_fine);
}
/* find starting point of read */
boStart_of_read = (ULONGLONG)( spnCurr ) * BD_TSPACKETSIZE;
/* find maximum ending point of read */
boNext_fine = (ULONGLONG)( spnNext ) * BD_TSPACKETSIZE;
/***
* For timebased slideshow (apptype==2), we need to play from the boFirst that was calculated
* above even if this is not the start of the EP_map. This is to fix content where IG (or other
* in-mux data) is encoded before the start of the EP_map.
***/
if ( (bAppType == 2) && (ci == 0) && (fi == 0) )
{
boStart_of_read = boFirst;
}
/* initialization of boEnd_of_read not really necessary, but removes a compiler warning */
boEnd_of_read = boStart_of_read;
/***
* For timebased slideshow (apptype==2), we need to send two sets of data for each browsing unit.
* One for the I-frame (and signal seq-end), and one for the rest of the data in the browsing unit.
*
* Normal trickmode playback will only do this loop once and will signal seq-end.
***/
bApp2loop = 0;
do
{
bApp2loop++;
if (bApp2loop == 2)
{
boStart_of_read = boEnd_of_read;
}
/* find ending point of read (depends on mode and I_end_position_offset) */
if ( (bDiscrete || ( (bAppType == 2) && (bApp2loop == 1) ) ) && (pClpInfoEpMapFine[fi].I_end_position_offset != 0) && (pClpInfoEpMapFine[fi].I_end_position_offset != 7))
{
/* if we're in discrete mode and the I_end_position_offset is valid, read from the posiiton of the fine to the I_end_posiiton_offset */
boEnd_of_read = boStart_of_read + I_tp_size[pClpInfoEpMapFine[fi].I_end_position_offset];
if (boEnd_of_read > boNext_fine)
{
boEnd_of_read = boNext_fine;
bApp2loop = 2;
}
}
else
{
/* if not, read from the position of the fine to the position of the next fine (or, if we're at the end, read to the end) */
boEnd_of_read = boNext_fine;
}
/* Handle "soft" edge conditions */
if (boStart_of_read < boFirst)
{
boStart_of_read = boFirst;
}
if (boEnd_of_read > boLast)
{
boEnd_of_read = boLast;
}
/* handle "hard" edge conditions - this could potentially happen briefly at edges, so don't cause failure, just notify */
if ( (boStart_of_read <= boLast) && (boEnd_of_read >= boFirst) && (boStart_of_read < boEnd_of_read) )
{
GetAndSend(hFileHandle, boStart_of_read, boEnd_of_read, fDataDiscontinuity, (bApp2loop == 1), pvContext);
}
else
{
DbgPrint(("Attempt to read off of or at the edge of trick boundaries (ok to see this print once at each edge condition)\n"));
DbgPrint(("boStart_of_read: %llu\n", boStart_of_read));
DbgPrint(("boFirst: %llu\n", boFirst));
DbgPrint(("boEnd_of_read: %llu\n", boEnd_of_read));
DbgPrint(("boLast: %llu\n", boLast));
/* if this happens, don't do the second half of the timebased slideshow loop */
break;
}
}while( (bAppType == 2) && (bDiscrete == 0) && (bApp2loop < 2) );
/* if we should stop, then stop */
if (m_fAbort == TRUE)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("%s() -- abort\n", __FUNCTION__));
goto out;
}
/* increment the fine index */
fi += (bDiscrete != 0) ? (increment * bDiscrete) : increment;
}
/* increment the coarse index */
ci += increment;
}
}
else /* continuous normal forward playback */
{
ULONGLONG boStart_of_read = boFirst;
ULONG spnIn, spnOut, ciNewStart, fiNewStart;
LocalContext *lcTemp;
BOOLEAN fLoop;
ULONG ulJumpIndex = 0;
LONG lPayloadsSent;
/* disk error handling loop */
do
{
fLoop = FALSE;
/* normal call to play - returns with the number of payloads sent (negative if ended in error) */
lPayloadsSent = GetAndSend(hFileHandle, boStart_of_read, boLast, fDataDiscontinuity, FALSE, pvContext);
/* if GetAndSend ended in error */
if ((lPayloadsSent <= 0) && (m_fAbort != TRUE))
{
/* if more than the specified number of payloads were sent on this last try, reset the loop counter */
if(lPayloadsSent < (-1*RESETJUMP))
{
ulJumpIndex = 0;
}
DBGPRINT(DBG_ON(DBG_ERROR), ("\nGetAndSend Failure - Disk Error %u! - Jumping %u EP_map entries to avoid errors.\n", ulJumpIndex, ERROR_JUMP(ulJumpIndex)+1));
lcTemp = m_lcManager.CurrentLocalContext();
spnIn = lcTemp->spnOfPayload;
/* find current EP map location */
if ( CLPINFO_SUCCESS == m_clpInfo.ClpInfoSearch_CoarseAndFineForSPN(spnIn, &ciNewStart, &fiNewStart))
{
DBGPRINT(DBG_ON(DBG_TRACE), ("currently at: (%u , %u) = 0x%x\n", ciNewStart, fiNewStart, spnIn));
ULONG fiNext;
ULONG ciNext;
fiNext = fiNewStart + (ULONG)(ERROR_JUMP(ulJumpIndex));
if (CLPINFO_SUCCESS != m_clpInfo.ClpInfoSearch_CoarseForFine(ciNewStart, m_clpInfo.ClpInfoGet_ciEnd(), fiNext, &ciNext, &spnOut))
{
DbgPrint(("ERROR - UNHANDLED ERROR"));
}
DBGPRINT(DBG_ON(DBG_ERROR), ("new position at: (%u , %u) = 0x%x\n", ciNext, fiNext, spnOut));
boStart_of_read = (ULONGLONG)spnOut * BD_TSPACKETSIZE;
ulJumpIndex++;
fLoop=TRUE;
}
if (m_event != NULL)
{
m_event(m_pContext, DR_EVENT_ERROR, (PVOID)DR_DISK_ERROR); /* send event */
}
/* Tell the PE that there was an error - opportunity for a decoder flush */
streamMessage.ErrorDiscontinuity = TRUE;
streamMessage.DataDiscontinuity = TRUE;
streamMessage.BegOfStream = FALSE;
streamMessage.EndOfStream = FALSE;
streamMessage.StreamContext = pvContext;
drSendStream(streamMessage, NULL);
streamMessage.ErrorDiscontinuity = FALSE;
streamMessage.DataDiscontinuity = FALSE;
}
fDataDiscontinuity = FALSE;
}while(fLoop == TRUE);
}
if ((fSendEOS) && (m_fAbort == FALSE))
{
streamMessage.BegOfStream = FALSE;
streamMessage.EndOfStream = TRUE;
streamMessage.StreamContext = pvContext;
drSendStream(streamMessage, NULL);
}
DBGPRINT(DBG_ON(DBG_TRACE), ("end of dataRetrieve\n"));
out:
if (hFileHandle != 0)
{
if (LOADER_SUCCESS != LoaderFileClose(m_loader, hFileHandle) )
{
DBGPRINT(DBG_ON(DBG_ERROR), ("\ndataRetrieve() -- ERROR Closing File: 0x%x\n\n", hFileHandle));
}
hFileHandle = 0;
}
return(status);
}
#ifdef DRM_SUPPORT
/**
* drGetKey - get the key for the current play item
*
* @param playList_id - the current play list id
* @param playItem_id - the current play Item id
* @param cps_unit - the current cps unit
*
* @retval none
*
* @remarks none.
*
*/
DR_ERROR DRPrefetch_BDROM::drGetKey(ULONG playList_id, ULONG playItem_id, ULONG title_num, ULONGLONG boFirst)
{
cPayload *pStreamPayload = NULL;
DROUTPUTMESSAGE streamMessage;
DR_ERROR status = DR_SUCCESS;
streamMessage.fInfoPayload = TRUE;
/* Get a payload buffer to work with */
pStreamPayload = drGetPayload();
if (NULL != pStreamPayload)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -