⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dr_prefetch_dvd.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    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 + -