📄 dr_prefetch_dvd.cpp
字号:
dsi_packet.sml_pbi.nxt_ilvu_sz = MAKE_WORD(&buf[n]);
n += 2;
/* get VOB_V_S_PTM */
dsi_packet.sml_pbi.vob_v_s_ptm = MAKE_DWORD(&buf[n]);
n += 4;
/* get VOB_V_E_PTM */
dsi_packet.sml_pbi.vob_v_e_ptm = MAKE_DWORD(&buf[n]);
n += 4;
for (i = 0; i < 8; i++)
{
/* get VOB_A_STP_PTM1 for each audio stream number */
dsi_packet.sml_pbi.vob_a_stp_ptm1[i] = MAKE_DWORD(&buf[n]);
n += 4;
/* get VOB_A_STP_PTM2 for each audio stream number */
dsi_packet.sml_pbi.vob_a_stp_ptm2[i] = MAKE_DWORD(&buf[n]);
n += 4;
}
for (i = 0; i < 8; i++)
{
/* get VOB_A_GAP_LEN1 for each audio stream number */
dsi_packet.sml_pbi.vob_a_gap_len1[i] = MAKE_DWORD(&buf[n]);
n += 4;
/* get VOB_A_GAP_LEN2 for each audio stream number */
dsi_packet.sml_pbi.vob_a_gap_len2[i] = MAKE_DWORD(&buf[n]);
n += 4;
}
/* next parse the SML_AGLI for a total of 54 bytes */
for (i = 0; i < MAX_ANGLES; i++)
{
dsi_packet.sml_agli[i].agl_c_dsta = MAKE_DWORD(&buf[n]);
n += 4;
dsi_packet.sml_agli[i].agl_c_sz = MAKE_WORD(&buf[n]);
n += 2;
}
/* next parse the VOBU_SRI for a total of 168 bytes */
for (i = 0; i < 42; i++)
{
dsi_packet.vobu_sri[i] = MAKE_DWORD(&buf[n]);
n += 4;
}
/* finally parse the SYNCI for a total of 144 bytes */
for (i = 0; i < 8; i++)
{
dsi_packet.synci.a_synca[i] = MAKE_WORD(&buf[n]);
n += 2;
}
for (i = 0; i < 32; i++)
{
dsi_packet.synci.sp_synca[i] = MAKE_DWORD(&buf[n]);
n += 4;
}
return (DR_SUCCESS);
}
/**
* drGetVobuEndAddr - get the VOBU end address
*
* @param dsi_packet - the dsi packet
* @param read_until_ref - which end address do we want?
* @param ulNavPackLBN - the VOBU start address
*
* @retval none
*
* @remarks none.
*/
inline ULONG drGetVobuEndAddr(dsipkt_struct *dsi_packet, ULONG read_until_ref, ULONG ulNavPackLBN)
{
ULONG ulVobuEndAddr;
switch (read_until_ref)
{
case DR_UNTIL_1STREF_EA:
ulVobuEndAddr = ulNavPackLBN + dsi_packet->dsi_gi.vobu_1stref_ea;
break;
case DR_UNTIL_2NDREF_EA:
ulVobuEndAddr = ulNavPackLBN + dsi_packet->dsi_gi.vobu_2ndref_ea;
break;
case DR_UNTIL_3RDREF_EA:
ulVobuEndAddr = ulNavPackLBN + dsi_packet->dsi_gi.vobu_3rdref_ea;
break;
case DR_NORMAL_PLAYBACK:
default:
ulVobuEndAddr = ulNavPackLBN + dsi_packet->dsi_gi.vobu_ea;
break;
}
return (ulVobuEndAddr);
}
/**
* drGetNextSectorAddr - get the next sector address
*
* @param dsi_packet - the dsi packet
* @param ulFirst - the next sector's start address
* @param ulLast - the next sector's end address
* @param ulVobuEndAddr - the current VOBU end address
* @param ulNavPackLBN - the current VOBU start address
*
* @retval none
*
* @remarks none.
*/
inline ULONG DRPrefetch_DVD::drGetNextSectorAddr(dsipkt_struct *dsi_packet, ULONG &ulFirst, ULONG &ulLast, ULONG ulVobuEndAddr, ULONG ulNavPackLBN)
{
#define NEXT_VOBU_LBN(x, y) ( (SRI_END_OF_CELL & x) == SRI_END_OF_CELL ? SRI_END_OF_CELL : (y + (SRI_END_OF_CELL & x)) )
ULONG ulNextSector;
if (m_skip_vobu <= DR_FWDI_NEXT) /* playing forward */
{
/* is this the last VOBU? */
if (ulVobuEndAddr < ulLast)
{
/* This is not the end so determine which sector is next */
/* first get the next sector using the vobu_sri info
* if a seamless angle change takes place it will over write this with the new
* sector start LBN */
ulNextSector = NEXT_VOBU_LBN(dsi_packet->vobu_sri[m_skip_vobu], ulNavPackLBN);
/* are we doing a seamless angle change? */
if (m_fAngleChangeInProgress == TRUE)
{
ULONG ulNextVOBU = NEXT_VOBU_LBN(dsi_packet->vobu_sri[DR_FWDI_NEXT], ulNavPackLBN);
/* Is the next navpack at the beginning of an ilvu?
* if so use the seeamless angle info to determine the next vobu sector */
if (ulNextVOBU == dsi_packet->sml_pbi.nxt_ilvu_sa + ulNavPackLBN)
{
if ( ( (dsi_packet->sml_agli[m_angle - 1].agl_c_dsta + ulNavPackLBN) >= m_angleStartAddr) &&
( (dsi_packet->sml_agli[m_angle - 1].agl_c_dsta + ulNavPackLBN) < m_angleEndAddr) )
{
DBGPRINT(DBG_ON(DBG_TRACE), ("drGetNextSectorAddr: ANGLE CHANGE COMPLETE!\n"));
/* jump to the appropriate ilvu */
ulNextSector = NEXT_VOBU_LBN(dsi_packet->sml_agli[m_angle - 1].agl_c_dsta, ulNavPackLBN);
/* update the start and end for the new angle */
ulFirst = m_angleStartAddr;
ulLast = m_angleEndAddr;
/* we've complete the angle change so reset the angle change request */
m_angle = DR_NO_AGL_C;
m_fAngleChangeInProgress = FALSE;
}
}
}
}
else
{
/* this is the last vobu... set the current sector value to the end so we kick out */
ulNextSector = SRI_END_OF_CELL;
}
}
else /* rewind */
{
if ((SRI_END_OF_CELL & dsi_packet->vobu_sri[m_skip_vobu]) == SRI_END_OF_CELL)
{
ulNextSector = SRI_END_OF_CELL;
}
else
{
ulNextSector = ulNavPackLBN - (SRI_END_OF_CELL & dsi_packet->vobu_sri[m_skip_vobu]);
}
/* are we doing a seamless angle change? */
if (m_fAngleChangeInProgress == TRUE)
{
#if DBG_ON(DBG_TRACE)
DbgPrint(("\ndrGetNextSectorAddr: m_angle=%d, start=%x, end=%x\n", m_angle, m_angleStartAddr, m_angleEndAddr));
DbgPrint(("drGetNextSectorAddr: firstLBN=%x, lastLBN=%x, NavPckLBN=%x\n", ulFirst, ulLast, ulNavPackLBN));
DbgPrint(("drGetNextSectorAddr: vobu_sri=%x\n", dsi_packet->vobu_sri[m_skip_vobu]));
DbgPrint(("drGetNextSectorAddr: nextLBN=%x\n", ulNavPackLBN - (SRI_END_OF_CELL & dsi_packet->vobu_sri[m_skip_vobu])));
DbgPrint(("drGetNextSectorAddr: vobu_sml_cat=%x\n", dsi_packet->sml_pbi.vobu_sml_cat));
DbgPrint(("drGetNextSectorAddr: sml_agli=%x\n\n", dsi_packet->sml_agli[m_angle - 1].agl_c_dsta + ulNavPackLBN));
#endif
/* Is the next navpack at the beginning of an ilvu?
* if so use the seamless angle info to determine the next vobu sector */
if ( (dsi_packet->sml_pbi.vobu_sml_cat & (ILVU_FLAG | UNIT_START_FLAG)) == (ILVU_FLAG | UNIT_START_FLAG))
{
if ( ( (dsi_packet->sml_agli[m_angle - 1].agl_c_dsta + ulNavPackLBN) >= m_angleStartAddr) &&
( (dsi_packet->sml_agli[m_angle - 1].agl_c_dsta + ulNavPackLBN) < m_angleEndAddr) )
{
DBGPRINT(DBG_ON(DBG_TRACE), ("drGetNextSectorAddr: ANGLE CHANGE COMPLETE!\n"));
/* jump to the appropriate ilvu */
ulNextSector = NEXT_VOBU_LBN(dsi_packet->sml_agli[m_angle - 1].agl_c_dsta, ulNavPackLBN);
/* update the start and end for the new angle */
ulFirst = m_angleStartAddr;
ulLast = m_angleEndAddr;
/* we've complete the angle change so reset the angle change request */
m_angle = DR_NO_AGL_C;
m_fAngleChangeInProgress = FALSE;
}
}
}
}
/* Do we need to cancel the angle change? */
if (m_fAngleChangeInProgress == TRUE)
{
/*
* Check if the current vobu being read is before the the start of either the
* current angle cell or the new angle cell, or if the current vobu being read
* is after the end of either the current angle cell or the new angle cell. If
* either case is true, then cancel the angle change because we are reading
* outside of the intended angle block.
*/
if ( ( (ulNavPackLBN < m_angleStartAddr) && (ulNavPackLBN < ulFirst) ) ||
( (ulNavPackLBN > m_angleEndAddr) && (ulNavPackLBN > ulLast) ) )
{
DBGPRINT(DBG_ON(DBG_TRACE), ("drGetNextSectorAddr: ANGLE CHANGE CANCELLED!\n"));
m_angle = DR_NO_AGL_C;
m_fAngleChangeInProgress = FALSE;
}
}
return (ulNextSector);
}
/**
* AngleChange - change angles
*
* @param anglcmd - parameters of the angle change
*
* @retval none
*
* @remarks none.
*/
DR_ERROR DRPrefetch_DVD::AngleChange(ANGLECMD *anglcmd)
{
DR_ERROR status = DR_SUCCESS;
ULONG angle = anglcmd->ulAngle;
ULONG startLBN = anglcmd->ulStartAngleCellAddr;
ULONG endLBN = anglcmd->ulEndAngleCellAddr;
/* Take angle change critical section */
OS_SemTake(m_semAngleChg, OS_WAIT_FOREVER);
#if DBG_ON(DBG_TRACE)
DbgPrint(("\nDR_SET_DVD_ANGLE: m_angle=%d, start=%x, end=%x\n", angle, startLBN, endLBN));
DbgPrint(("DR_SET_DVD_ANGLE: vobu_sri=%x\n", m_dsi_packet.vobu_sri[m_skip_vobu]));
DbgPrint(("DR_SET_DVD_ANGLE: nextLBN=%x\n", m_ulNavPackLBN - (SRI_END_OF_CELL & m_dsi_packet.vobu_sri[m_skip_vobu])));
DbgPrint(("DR_SET_DVD_ANGLE: vobu_sml_cat=%x\n", m_dsi_packet.sml_pbi.vobu_sml_cat));
DbgPrint(("DR_SET_DVD_ANGLE: sml_agli=%x\n\n", m_dsi_packet.sml_agli[m_angle - 1].agl_c_dsta + m_ulNavPackLBN));
#endif
if (m_skip_vobu >= DR_BWDI_PREV) /* if we're going backwards */
{
if ((SRI_END_OF_CELL & m_dsi_packet.vobu_sri[m_skip_vobu]) == SRI_END_OF_CELL)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("DR_SET_DVD_ANGLE: ERROR - SRI_END_OF_CELL\n"));
status = DR_FAILURE;
}
else
{
ULONG ulNextSector = m_ulNavPackLBN - (SRI_END_OF_CELL & m_dsi_packet.vobu_sri[m_skip_vobu]);
/* if we've already read past the angle block then fail the call */
if (ulNextSector < startLBN)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("DR_SET_DVD_ANGLE: ERROR - already past the angle block\n"));
status = DR_FAILURE;
}
}
}
if (status == DR_SUCCESS)
{
m_fAngleChangeInProgress = TRUE;
m_angle = angle;
m_angleStartAddr = startLBN;
m_angleEndAddr = endLBN;
}
/* Give angle change critical section */
OS_SemGive(m_semAngleChg);
return(status);
}
/**
* SetSpeed - change speed
*
* @param ulSkipVobu - the value of skip_vobu to use
* @param ulReadUntilRef - the value of read_until_ref to use
*
* @retval none
*
* @remarks none.
*/
DR_ERROR DRPrefetch_DVD::SetSpeed(SPEEDCMD *speedcmd)
{
m_skip_vobu = speedcmd->skip_vobu;
m_read_until_ref = speedcmd->read_until_ref;
return(DR_SUCCESS);
}
/**
* GetPlayRate - return the play rate
*
* @param none
*
* @retval the play rate as a field of two 16-bit values.
*
* @remarks none.
*/
uint32 DRPrefetch_DVD::GetPlayRate(void)
{
return((m_read_until_ref << 16) | m_skip_vobu);
}
/**
* GetCellPosition - return cell position information of current cell being read
*
* @param none
*
* @retval cell id
*
* @remarks none.
*/
ULONG DRPrefetch_DVD::GetCellPosition(void)
{
return (m_ulCellPosition);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -