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

📄 pe_consumer_dvd.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                }
            }

            /* also check the pts if we are not in E_STD active mode */
            if (m_E_STD_Active == FALSE)
            {
                /* this is for the case that avsync is out or we are in slow/pause trick modes */
                if ( (time90k_NavPackPTS <= time90k_PTS) && (time90k_PTS < (time90k_NavPackPTS + 900000) ) )
                {
                    DBGPRINT(DBG_ON(DBG_NVPCK), ("NavPackAVSync: USING PTS\n"));
                    break;
                }
            }

            OS_TaskDelayMsec(20);
        }
        else
        {
            /*
             * FF/REW Trickmode
             */
            ULONG ulNewTickCount = OS_GetTicks();

            /* fastfwd/rewind rates are throttled by the navpacks.
             * this eliminates difficulties with trying to sync to PTS values in trickmode */

            /* if clock rolled over just send this navpack out */
            if (ulNewTickCount < ulLastTickCount)
            {
                DBGPRINT(DBG_ON(DBG_NVPCK), ("NavPackAVSync: clock rolled over\n"));
                break;
            }

            /* determine how much time has passed since the last navpack was sent */
            offset = ((ulNewTickCount - ulLastTickCount) / (OS_GetTickRate() / 1000)) * 90;

            /* adjust according to playrate - m_playrate.rate must be > PLAY_RATE_NORMAL */
            offset *= (m_playrate.rate / PLAY_RATE_NORMAL);

            /* if we're in reverse step - just send the navpack */
            if ( (m_playrate.rate == PLAY_RATE_STEP) && (m_playrate.direction == PE_ISTREAMCTRL_DIRECTION_BACKWARD) )
            {
                break;
            }

            if (m_playrate.direction == PE_ISTREAMCTRL_DIRECTION_FORWARD)
            {
                /* check the current time info */
                if (m_time90k_NavPackPTS + offset >= time90k_NavPackPTS)
                {
                    /* if we are going forward in trick mode look for forward rollover */
                    if (m_E_STD_Active == TRUE)
                    {
                        DBGPRINT(DBG_ON(DBG_NVPCK), ("m_E_STD_Active off in fordward trick mode\n\n\n"));
                        m_E_STD_Active  = FALSE;
                        m_E_STD_Offset  = 0;
                        m_E_STD_Time = 0;
                    }
                    break;
                }
            }
            else
            {
                /* check the current time info */
                if (m_time90k_NavPackPTS < time90k_NavPackPTS + offset)
                {
                    if (m_E_STD_Active == TRUE)
                    {
                        /* if the PTS rolls over we have crossed into the next VOB */
                        DBGPRINT(DBG_ON(DBG_NVPCK), ("m_E_STD_Active off in backward trick mode\n"));
                        m_E_STD_Active  = FALSE;
                        m_E_STD_Offset  = 0;
                        m_E_STD_Time = 0;
                    }
                    break;
                }
            }
            OS_TaskDelayMsec(20);
        }

        PrevPTSValid = TRUE;
        time90k_PrevPTS = time90k_PTS;
    }

    PrevPTSValid = TRUE;
    time90k_PrevPTS = time90k_PTS;

    DBGPRINT(DBG_ON(DBG_NVPCK), ("NavPackAVSync - FINISHED - PTS=%ld, STC=%ld\n",
        time90k_PTS, time90k_STC));
}

/**
 * cPEConsumer_DVD::NavPackTask
 *
 * @param pvParam
 *
 * @return PE_STATUS
 */
ULONG cPEConsumer_DVD::NavPackTask(PVOID pvParam)
{
    DEMUXOUTPUTMESSAGE              *pMessage          = NULL;
    cPayload                        *pPayload1         = NULL;
    cPayload                        *pPayload2         = NULL;
    BOOLEAN                         fVideoExists       = FALSE;
    TIME90k                         time90k_NavPackPTS = 0;
    BOOLEAN                         ESTD_GetOffset     = 0;
    BYTE                            *buf               = NULL;
    ULONG                           ulNavPckID;
    PE_NVPCK_EVENT_INFO             info;
    TIME45k                         time45k_CurrSTC;
    TIME45k                         time45k_CurrPTS;
    PE_STATUS                       status;

    if (pvParam == NULL)
    {
        OS_TaskExit();
        return (PE_FAILURE);
    }

    /* setup E_STD Values */
    m_E_STD_Offset  = 0;
    m_E_STD_StartPTM = 0;
    m_E_STD_EndPTM  = 0;
    m_E_STD_Time    = 0;
    m_E_STD_RolledOver = FALSE;
    m_E_STD_Active  = FALSE;
    m_LastSPUTargetPTS = 0;
    m_LastTickCount = 0;

    m_fFlushNavPacks = FALSE;
    ulNavPckID       = 0;
    m_NvPckSyncState = PE_NVPCK_SYNC_FIRST;

    /* Sit and spin forever */
    while (1)
    {
        /* reset the navpack payload pointers */
        if (pPayload1 != NULL)
        {
            delete pPayload1;
            pPayload1 = NULL;
        }
        if (pPayload2 != NULL)
        {
            delete pPayload2;
            pPayload2 = NULL;
        }

        /* if it hasn't been done yet release the previous navpack message */
        if (pMessage != NULL)
        {
            if (pMessage->payload != NULL)
            {
                /* release the payload */
                delete (pMessage->payload);
            }

            /* if notification of message done is requested give it now */
            if (pMessage->semMsgDone)
            {
                DBGPRINT(DBG_ON(DBG_TRACE), ("NavPackTask: notification of message done\n"));
                OS_SemGive(pMessage->semMsgDone);
            }

            /* Do end of stream processing */
            if (pMessage->EndOfStream == TRUE)
            {
                DBGPRINT(DBG_ON(DBG_TRACE), ("NavPackTask: notification of end of stream\n"));

                /* if this is the last VOBU of a cell with VOBU Stills then we need
                 * to block until the still has been released */
                if (pMessage->fIsVobuStill == TRUE)
                {
                    while (m_fPauseAfterVOBU == TRUE)
                    {
                        OS_TaskDelayMsec(100);
                        if (m_fAbort == TRUE)
                        {
                            m_fPauseAfterVOBU = FALSE;
                            break;
                        }
                    }
                }

                /* call base class for end of stream processing */
                cPEConsumer::ProcessEndOfStream(pMessage->StreamContext);
            }

            /* release the message */
            m_pNvPckStream->ReleaseMsg(pMessage);
            pMessage = NULL;
        }

        /* Get a navpack stream message */
        pMessage = (DEMUXOUTPUTMESSAGE*)m_pNvPckStream->Read(OS_WAIT_FOREVER);
        if (NULL == pMessage)
        {
            OS_TaskYield();
            continue;
        }

        /* check for an info packet */
        if (pMessage->fInfoPayload == TRUE)
        {
            /* ignore info packets */
            continue;
        }

        /* check for termination message */
        if (pMessage->fTerminate == TRUE)
        {
            DbgPrint(("\n>>>> NavPackTask TERMINATION MESSAGE <<<<\n\n"));
            goto navpack_task_exit;
        }

        /* Handle DiscontinuityAtBeginning messages */
        if (TRUE == pMessage->DiscontinuityAtBeginning)
        {
            DBGPRINT(DBG_ON(DBG_NVPCK), ("NavPackTask: DiscontinuityAtBeginning\n"));
        }

        /* complete flush on stop notification */
        if (TRUE == pMessage->fStopNotification)
        {
            DBGPRINT(DBG_ON(DBG_NVPCK), ("NavPackTask: fStopNotification\n"));
            m_fFlushNavPacks = FALSE;
            m_E_STD_Active   = FALSE;

            /* reset times */
            ESTD_GetOffset       = FALSE;
            m_E_STD_Active       = FALSE;
            m_E_STD_Offset       = 0;
            m_E_STD_Time         = 0;
            m_E_STD_RolledOver   = FALSE;
            m_time90k_NavPackPTS = 0;
            m_LastPTS            = 0;
            m_NvPckSyncState     = PE_NVPCK_SYNC_FIRST;
        }

        if (NULL != pMessage->payload)
        {
            int  n;
            TIME90k time90k_VOBU_S_PTM;

            TCH_PAYLOAD(pMessage->payload);

            status = PE_SUCCESS;

            /* Nav packets will always come in pairs since they reside in the same sector and we read a
             * sector at a time. The first packet will be a PCI packet followed by the DSI packet. */

            /* record current navpack ID */
            m_ulNavPckID = pMessage->ulVobuCC;

            /* make a reference for the pci packet */
            while (1)
            {
                pPayload1 = pMessage->payload->REF_PAYLOAD;
                if (pPayload1 != NULL)
                {
                    break;
                }
                OS_TaskYield();
            }
            pPayload1->set_wr_ptr((PVOID)((ULONG)(pPayload1->get_rd_ptr()) + 986));

            /* make a reference for the dsi packet */
            while (1)
            {
                pPayload2 = pMessage->payload->REF_PAYLOAD;
                if (pPayload2 != NULL)
                {
                    break;
                }
                OS_TaskYield();
            }
            pPayload2->set_rd_ptr((PVOID)((ULONG)(pPayload2->get_rd_ptr()) + 986));

            /* release the payload */
            delete (pMessage->payload);
            pMessage->payload = NULL;

            /* validate the PCI packet header */
            buf = (BYTE*)pPayload1->get_rd_ptr();
            for (n = 0; n < 7; n++)
            {
                if (buf[n] != PCI_STRT[n])
                {
                    DbgPrint(("%s, %d: PCI Invalid!\n", __FILE__, __LINE__));
                    status = PE_FAILURE;
                    break;
                }
            }

            /* get the vobu_start_ptm */
            time90k_VOBU_S_PTM = MAKE_DWORD(&buf[19]);

            /* if we are in estd, then the next navpack will give us the
             * start ptm of the next vobu so we can find the STC delta */
            if (ESTD_GetOffset == TRUE)
            {
                ESTD_GetOffset = FALSE;
                m_E_STD_StartPTM = MAKE_DWORD(buf + 19);
                m_E_STD_Offset = m_E_STD_EndPTM - m_E_STD_StartPTM;
                m_E_STD_Active = TRUE;
                DBGPRINT(DBG_ON(DBG_NVPCK), ("ESTD ACTIVE offset %d, estd active %d, start time %d\n\n", m_E_STD_Offset, m_E_STD_Active, m_E_STD_StartPTM));
            }

            /* validate the DSI packet header */
            buf = (BYTE*)pPayload2->get_rd_ptr();
            for (n = 0; n < 7; n++)
            {
                if (buf[n] != DSI_STRT[n])
                {
                    DbgPrint(("%s, %d: DSI Invalid!\n", __FILE__, __LINE__));
                    status = PE_FAILURE;
                    break;
                }
            }

            /* get the nav pack pts (navpack scr from the DSI) */
            /* elm: OR, use the VOBU_S_PTM if it's less than the navpack scr.  This *should* never happen, but it does */
            time90k_NavPackPTS = MIN(MAKE_DWORD(&buf[7]), time90k_VOBU_S_PTM);

            /* check if video exists in the vobu...
             * In Blue Book Part 3 is states VOBU_1STREF_EA will equal 0 if there is no video data present */
            fVideoExists = (MAKE_DWORD(&buf[19]) == 0) ? FALSE : TRUE;

#if DBG_ON(DBG_NVPCK)
            DBGPRINT((fVideoExists == FALSE), ("****** NavPackTask: VIDEO DATA DOES NOT EXIST ******\n"));
#endif
        }
        else
        {
            status = PE_FAILURE;
        }

        if (PE_SUCCESS == status)
        {
#ifndef __DISABLE_SYNC
            /* syncronize to the video stream */
            if (time90k_NavPackPTS != 0xffffffff)
            {
                NavPackAVSync(time90k_NavPackPTS, m_LastTickCount, fVideoExists);
            }
#endif

            /* update navpck synch state */
            m_NvPckSyncState = (m_NvPckSyncState == PE_NVPCK_SYNC_FIRST) ? PE_NVPCK_SYNC_SECOND : PE_NVPCK_SYNC_NORMAL;

            /* send the navpack off to the navigator */
            if (m_fFlushNavPacks == FALSE)
            {
                /* send the navpack to the nav */
                info.pPCIpayload = pPayload1->get_rd_ptr();
                info.pDSIpayload = pPayload2->get_rd_ptr();

                status = SendEvent(PE_EVENT_NVPCK, &info);

                /* update the PTS */
                if (GetVidPTS(&time45k_CurrPTS, &time45k_CurrSTC) != PE_SUCCESS)
                {
                    DbgPrint(("NavPackTask: Failed to get video pts\n"));
                }

                /* take a sem and update the member times related to navpacks */
                OS_SemTake(m_semNavPackState, OS_WAIT_FOREVER);

                m_time90k_NavPackPTS = time90k_NavPackPTS;
                m_LastPTS = time45k_CurrPTS * 2;
                m_LastTickCount = OS_GetTicks();

                OS_SemGive(m_semNavPackState);

                /* if the nav pack triggers an E_STD_active condition
                 * set a flag for it, otherwise clear it */
                if (status == PE_EVNT_E_STD_ACTIVE)
                {
                    /* get the end ptm of this packet */
                    buf = (BYTE*)pPayload1->get_rd_ptr();
                    m_E_STD_EndPTM = MAKE_DWORD(buf + 23);

                    /* get the offset on the next navpack, and turn on ESTD active */
                    ESTD_GetOffset = TRUE;
                }
            }
            else
            {
                DBGPRINT(DBG_ON(DBG_NVPCK), ("PENavPackTask: m_fFlushNavPacks!

⌨️ 快捷键说明

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