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

📄 pe_consumer_dvd.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
 *
 * @param StreamContext
 *
 * @return None
 */
PE_STATUS cPEConsumer_DVD::ProcessEndOfStream(PVOID StreamContext)
{
    /*
     * Do not do anything.  The End Of Stream event will get processed from NavPackTask
     * when the last vobu is being presented.
     */
    return (PE_SUCCESS);
}

/**
 * If active start consuming and presenting AV data.
 *
 * @return PE_STATUS
 */
PE_STATUS cPEConsumer_DVD::processData(PEINPUTMESSAGE *pInMessage)
{
    BYTE  *pbData = NULL;
    ULONG ulSize  = 0;

    TCH_PAYLOAD(pInMessage->payload);

    if (pInMessage->fInfoPayload)
    {
        return(PE_FAILURE);
    }


    /* get payload info */
    pbData = (BYTE*)pInMessage->payload->get_rd_ptr();
    ulSize = (ULONG)pInMessage->payload->get_size();

    /* if the data is encrypted then decrypt it */
    if (CSS == pInMessage->Encryption)
    {
        BYTE *pbSector;
        int  sector_cnt = ulSize/2048;
        register int i;

        for (i = 0; i < sector_cnt; i++)
        {
            pbSector = pbData + i*2048;

            if ( CSSDescramble( pbSector, m_DecodeKey ) != CSS_SUCCESS ) 
            {
                DBGPRINT(DBG_ON(DBG_TRACE),("ERROR: CSSDescramble failed\n"));
            }

            m_FirstTitleKeyPack = FALSE;
        }
    }

    /* send the payload to the psdemux
     * this will in turn feed the decode playback */
    SendStreamMsgToDemux(pInMessage->payload, pInMessage);

    return (PE_SUCCESS);
}

/**
 * Process an info payload
 *
 * @return PE_STATUS
 */
PE_STATUS cPEConsumer_DVD::processInfo(PEINPUTMESSAGE *pInMessage)
{
    INFOPAYLOAD *infoPayload;

    /* get payload info */
    infoPayload = (INFOPAYLOAD*)pInMessage->payload->get_base_ptr();

    /* Check for encryption key */
    if (infoPayload->bType == INFOTYPE_CRYPTKEY)
    {
        BYTE  *pbData = NULL;
        ULONG ulSize  = 0;

        pbData = infoPayload->data_packet.data;
        ulSize = infoPayload->data_packet.size;

        /* The payload is an encryption key, we need to save this */
#if DBG_ON(DBG_TRACE)
        {
            ULONG i;
            DbgPrint(("Decode Key: "));
            for (i = 0; i < ulSize; i++)
            {
                DbgPrint(("  %02x", pbData[i]));
            }
            DbgPrint(("\n"));
        }
#endif

        /* This is just a simple way of telling if we have a cleartext key or a key handle */
        if (ulSize == 5)
        {
            memcpy(&m_DecodeKey, pbData, ulSize);
        }
        else if (ulSize == 4)
        {
            /* SDK: delete css key if the decoder API uses key handles */
            m_FirstTitleKeyPack = TRUE;
        }
        goto exit;
    }

    /* check for VOBU packet */
    if (infoPayload->bType == INFOTYPE_VOBUINFO)
    {
        if ( (m_playrate.rate == PLAY_RATE_STEP) && (m_playrate.direction == PE_ISTREAMCTRL_DIRECTION_BACKWARD) )
        {
            m_fPauseAfterVOBU = TRUE;
        }

        /* If we are in VOBU still mode then we wait here for the still to be released.
         * This will hold off data from the decoder/spu/navpack tasks */
        while (m_fPauseAfterVOBU == TRUE)
        {
            OS_TaskDelayMsec(100);

            if (m_fAbort == TRUE)
            {
                m_fPauseAfterVOBU = FALSE;
                goto exit;
            }
        }

        /* now check if the next vobu is a vobu still */
        if ( infoPayload->vobu.fIsVobuStill == TRUE )
        {
            m_fPauseAfterVOBU = TRUE;
        }
        else
        {
            m_fPauseAfterVOBU = FALSE;
        }
        goto exit;
    }

    /* check for INFOTYPE_TIMEPACK packet */
    if (infoPayload->bType == INFOTYPE_TIMEPACK )
    {
        pInMessage->semMsgDone = m_semPSDemxMsgSync;
    }

    /* send the info payload to the psdemux
     * this will in turn send it to all of the output pins */
    SendStreamMsgToDemux(pInMessage->payload, pInMessage);

exit:
    return (PE_SUCCESS);
}

/**
 * cPEConsumer_DVD::NavPackAVSync
 *
 * @return PE_STATUS
 */
void cPEConsumer_DVD::NavPackAVSync(TIME90k time90k_NavPackPTS, ULONG ulLastTickCount, BOOLEAN fVideoExists)
{
    VDVD_ERROR          error           = VDVD_SUCCESS;
    static TIME90k      time90k_PrevPTS = 0;
    TIME90k             time90k_PTS     = 0;
    TIME90k             time90k_STC     = 0;
    TIME45k             time45k_PTS;
    TIME45k             time45k_STC;
    int                 offset          = 0;
    BOOLEAN             PrevPTSValid    = FALSE;
    DECODE_STATUS_TYPE  d_status;

    if (m_NvPckSyncState == PE_NVPCK_SYNC_FIRST)
    {
        return;
    }

    DBGPRINT(DBG_ON(DBG_NVPCK), ("NavPackAVSync - STARTING - nvpckPTS=%ld, VideoExist=%d\n",
        time90k_NavPackPTS, fVideoExists));

    while (FALSE == m_fFlushNavPacks)
    {
        if (m_playrate.discontiguous == FALSE)
        {
            if (m_videoDecode[0] != NULL)
            {
                /* TODO-SDK - Get the current PTS and STC of the decoder. */
                error = m_videoDecode[0]->GetStatus(&d_status);
            }
            else if (m_videoDecode[1] != NULL)
            {
                error = m_videoDecode[1]->GetStatus(&d_status);
            }
            else if (m_audioDecode[0] != NULL)
            {
                /* TODO-SDK - Get the current PTS and STC of the decoder. */
                error = m_audioDecode[0]->GetStatus(&d_status);
            }
            else if (m_audioDecode[1] != NULL)
            {
                error = m_audioDecode[1]->GetStatus(&d_status);
            }

            if (fVideoExists == TRUE)
            {
                /* use video pts & scr when it exists */
                time45k_PTS = d_status.video_pts;
                time45k_STC = d_status.video_stc;
            }
            else
            {
                /* use audio pts & scr since there is not video in this VOBU */
                time45k_PTS = d_status.audio_pts;
                time45k_STC = d_status.audio_stc;
            }

            /* navpack PTS is 90k so scale 45k value to 90k
             * Note: keep bit0 so that values of 0x0 and 0xffffffff are still possible */
            time90k_PTS = (time45k_PTS * 2) | (time45k_PTS & 0x00000001);
            time90k_STC = (time45k_STC * 2) | (time45k_STC & 0x00000001);
        }
        else
        {
            time90k_PTS = 0;
            time90k_STC = 0;
        }

        DBGPRINT(DBG_ON(DBG_NVPCK), ("NavPackAVSync: decoder info: PTS:%d, STC:%d\n",time45k_PTS,time45k_STC ));

        /*
         * if this is the first navpack then send it right away
         */
        if (m_E_STD_Active == FALSE)
        {
            if ( (time90k_NavPackPTS == 0) && (m_playrate.direction == PE_ISTREAMCTRL_DIRECTION_FORWARD) )
            {
                DBGPRINT(DBG_ON(DBG_NVPCK), ("NavPackAVSync: first navpack\n"));
                break;
            }
        }

        /*
         * If the data is contiguous use timestamps
         */
        if (m_playrate.discontiguous == FALSE)
        {
            /*
             * slow/normal and IP-FF playrate
             */

            /* the STC is only useful for normal playrate */
            if ( (m_playrate.rate == PLAY_RATE_NORMAL) || (fVideoExists == FALSE) )
            {
                if (m_E_STD_Active == TRUE)
                {
                    /* get delta between current time and offset */
                    m_E_STD_Time = (LONG)time90k_STC - (LONG)m_E_STD_Offset;

                    if ((m_E_STD_Time >= m_E_STD_StartPTM) ||
                        ((m_E_STD_RolledOver == TRUE) && (m_E_STD_Time < 0)) )
                    {
                        /* also we need to be sure the decoder has actually transitioned, that means
                         * waiting for a PTS that is in the next VOBU */
                        if ((time90k_PTS >= m_E_STD_StartPTM) && (time90k_PTS < (m_E_STD_StartPTM + 90000)))
                        {
                            /* as soon as we roll over, turn off the estd */
                            DBGPRINT(DBG_ON(DBG_NVPCK), ("Turn OFF ESTD 1\n"));
                            m_E_STD_Active = FALSE;
                            m_E_STD_Offset = 0;
                            m_E_STD_Time = 0;
                            m_E_STD_RolledOver = FALSE;
                        }
                    }

                    /* if the clock becomes positive and we haven't already sent the 0 time
                     * navpack send it now */
                    if ((m_E_STD_Time >= 0) && (m_time90k_NavPackPTS != 0))
                    {
                        DBGPRINT(DBG_ON(DBG_NVPCK), ("Kick out navpack during ESTD\n"));
                        m_E_STD_RolledOver = TRUE;
                        break;
                    }

                    /* we are in a still and ESTD mode, we have a valid last pts and it's equal to current,
                     * we check active here because we may have just turned E_STD active off */
                    if ((time90k_PTS == time90k_PrevPTS) && (PrevPTSValid == TRUE) && (m_E_STD_Active == TRUE))
                    {
                        /* if we are in a still and still using the old clocking during an estd transition
                         * base the time on the stc offset from the previous navpack */
                        offset = ((OS_GetTicks() - ulLastTickCount) / (OS_GetTickRate() / 1000)) * 90;

                        if (m_time90k_NavPackPTS + offset > time90k_NavPackPTS)
                        {
                            DBGPRINT(DBG_ON(DBG_NVPCK), ("Turn off estd KICK STILL ESTD time %lu\n\n", m_time90k_NavPackPTS + offset));
                            m_E_STD_Active  = FALSE;
                            m_E_STD_Offset = 0;
                            m_E_STD_Time = 0;
                            m_E_STD_RolledOver = FALSE;
                            break;
                        }
                    }
                }
                else
                {
                    /* if video does not exist then calculate the amount of time that has passed
                     * since the last navpack was sent. This is only valid for normal playrate */
                    if ( (fVideoExists == FALSE) && (m_playrate.rate == PLAY_RATE_NORMAL) )
                    {
                        if ((time90k_PTS == time90k_PrevPTS) && (PrevPTSValid == TRUE))
                        {
                            /* determine how much time has passed since the last navpack was sent */
                            offset = ((OS_GetTicks() - ulLastTickCount) / (OS_GetTickRate() / 1000)) * 90;

                            if (m_time90k_NavPackPTS + offset > time90k_NavPackPTS + 9000)
                            {
                                DBGPRINT(DBG_ON(DBG_NVPCK), ("NavPackAVSync: USING LAST NVPACK PTS\n"));
                                break;
                            }
                        }
                    }

                    /* don't use the STC if AVSync appears to be out */
                    if ( (m_NvPckSyncState == PE_NVPCK_SYNC_NORMAL) ||
                         ((time90k_STC < time90k_PTS + 15000) && (time90k_PTS < time90k_STC + 15000)) )
                    {
                        offset = ((OS_GetTicks() - ulLastTickCount) / (OS_GetTickRate() / 1000)) * 90;

                        /* base sending navpacks on previous navpack send time and the offset between
                         * the current time and that one */
                        if (m_time90k_NavPackPTS + offset > time90k_NavPackPTS)
                        {
                            DBGPRINT(DBG_ON(DBG_NVPCK), ("NavPackAVSync: USING STC OFFSET\n"));
                            break;
                        }
                    }
                    else if ((time90k_PTS == time90k_PrevPTS) && (fVideoExists == TRUE))
                    {
                        /* if the pts isn't moving (we are at a still probably) and we have video
                         * use an offset based on the last navpack and the ticks since then */
                        offset = ((OS_GetTicks() - ulLastTickCount) / (OS_GetTickRate() / 1000)) * 90;

                        if (m_time90k_NavPackPTS + offset > time90k_NavPackPTS)
                        {
                            DBGPRINT(DBG_ON(DBG_NVPCK), ("NavPackAVSync: USING STC 2\n"));
                            break;
                        }
                    }
                }
            }
            else
            {
                /* if we are in the E_STD active zone handle the rollover cases to kick out */
                if (m_E_STD_Active == TRUE)
                {
                    /* get delta between current time and offset */
                    m_E_STD_Time = (LONG)time90k_PTS - (LONG)m_E_STD_Offset;

                    /* if we hit the start time of the next vobu turn off estd, also turn it
                     * off if we have already rolled over and the time appears to have gone negative (in
                     * this case the low pts value and the high E_STD_offset make the time < 0) */
                    if ((m_E_STD_Time >= m_E_STD_StartPTM) ||
                        ((m_E_STD_RolledOver == TRUE) && (m_E_STD_Time < 0)) )
                    {
                        DBGPRINT(DBG_ON(DBG_NVPCK), ("Turn off ESTD 2\n\n\n"));
                        m_E_STD_Active = FALSE;
                        m_E_STD_Offset = 0;
                        m_E_STD_Time = 0;
                        m_E_STD_RolledOver = FALSE;
                    }

                    /* if we hit the estd time and havent sent the 0 navpack, send it now
                     * Q: does this properly handle non-zero estd transitions?  is that possible? */
                    if ((m_E_STD_Time >= 0) && (m_time90k_NavPackPTS != 0))
                    {
                        DBGPRINT(DBG_ON(DBG_NVPCK), ("NavPackAVSync: Send navpack after estd2\n"));
                        m_E_STD_RolledOver = TRUE;
                        break;
                    }
                }
                else
                {
                    offset = time90k_PTS - m_LastPTS;

                    if (m_time90k_NavPackPTS + offset > time90k_NavPackPTS)
                    {
                        DBGPRINT(DBG_ON(DBG_NVPCK), ("NavPackAVSync: USING STC 2\n"));
                        break;
                    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -