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

📄 pbc_plcontrol.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                {
                    uint32 tmp_uiAngleNumber = uiAngleNumber;
                    hPBC->pCallback(hPBC->pvCallbackContext, PLAYCTRL_EVENT_ANGLECHANGE, &tmp_uiAngleNumber);
                }
            }
        }

        /* Notify UI if multi-angle is available or not */
        if (1 == pCurrentPlayItem->is_multi_angle)
        {
            ULONG message[4];
            message[0] = VDVD_STATUS_ANGLE_ON;
            UsrEventHandler(message);
        }
        else
        {
            ULONG message[4];
            message[0] = VDVD_STATUS_ANGLE_OFF;
            UsrEventHandler(message);
        }

        if ( (VDVD_CONNECTION_1                 == pPIContext->connection) ||
             (VDVD_CONNECTION_ABORT             == pPIContext->connection) ||
             (VDVD_CONNECTION_NONSEAMLESS_ANGLE == pPIContext->connection)  )
        {
            DR_STREAM stream_path;
            uint32  uiTmp;
            uint32  uiLastAudioStn;
            uint32  uiLastSubtitleStn;
            uint32  uiLastIGStn;

            DBGPRINT(DBG_ON(DBG_TRACE), ("PbcPLCtrlBegStream: non-seamless connection\n"));

            PEiStreamCtrlFlush(hPBC->hPE, INPUT_MAIN);

            /*
             * Set PSRs
             */

            /* Set Audio Stream Number (use upper bits from the current PSR) */
            if (PbcRegGetPSR(PLAYCTRL_PSR_AUDIO_STN, &uiTmp) != PLAYCTRL_SUCCESS)
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: Failed to get AudioStn!\n"));
                goto errout;
            }
            uiLastAudioStn = uiTmp & 0x000000ff;
            uiTmp = (pPIContext->StreamInfo.uiPrimaryAudioStn & 0x000000ff) | (uiTmp & 0xffffff00);

            if (PlayCtrlSetPSR(PLAYCTRL_PSR_AUDIO_STN, uiTmp) != PLAYCTRL_SUCCESS)
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: Failed to set audio stream number!\n"));
                goto errout;
            }

            /* Set PG/TEXTST Stream Number (use upper bits from the current PSR) */
            if (PbcRegGetPSR(PLAYCTRL_PSR_PG_AND_ST_STN, &uiTmp) != PLAYCTRL_SUCCESS)
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: Failed to get PG/TextST stream number!\n"));
                goto errout;
            }
            uiLastSubtitleStn = uiTmp & 0x00000fff;
            uiTmp = (pPIContext->StreamInfo.uiPGTextSTStn & 0x00000fff) | (uiTmp & 0xfffff000);

            if (PlayCtrlSetPSR(PLAYCTRL_PSR_PG_AND_ST_STN, uiTmp) != PLAYCTRL_SUCCESS)
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: Failed to set subtitle number!\n"));
                goto errout;
            }

            /* Set IG Stream Number (use upper bits from the current PSR) */
            if (PbcRegGetPSR(PLAYCTRL_PSR_IG_STN, &uiTmp) != PLAYCTRL_SUCCESS)
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: Failed to get IG Stn!\n"));
                goto errout;
            }
            uiLastIGStn = uiTmp & 0x000000ff;
            uiTmp = (pPIContext->StreamInfo.uiIGStn & 0x000000ff) | (uiTmp & 0xffffff00);

            if (PlayCtrlSetPSR(PLAYCTRL_PSR_IG_STN, uiTmp) != PLAYCTRL_SUCCESS)
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: Failed to set IG stream number!\n"));
                goto errout;
            }

            /*
             * If audio/subtitle stream PSRs have changed, then send callback events,
             * notifying application of the changes.
             */
            if (hPBC->pCallback != NULL)
            {
                if (uiLastAudioStn != pPIContext->StreamInfo.uiPrimaryAudioStn)
                {
                    uint32 tmp_uiPrimaryAudioStn = pPIContext->StreamInfo.uiPrimaryAudioStn;
                    hPBC->pCallback(hPBC->pvCallbackContext, PLAYCTRL_EVENT_AUDIOCHANGE, &tmp_uiPrimaryAudioStn);
                }

                if (uiLastSubtitleStn != pPIContext->StreamInfo.uiPGTextSTStn)
                {
                    uint32 tmp_uiPGTextSTStn = pPIContext->StreamInfo.uiPGTextSTStn;
                    hPBC->pCallback(hPBC->pvCallbackContext, PLAYCTRL_EVENT_SUBTITLECHANGE, &tmp_uiPGTextSTStn);
                }
            }

            /*
             * Configure Streams (if not discontiguous)
             */
            if (pPIContext->PlayRate.discontiguous == 0)
            {
                uint32 uiPrevPlayitemID;

                /*
                 * Get previous playitem ID.  The PSR hasn't been set with this new playitem ID yet,
                 * so the value from the PSR contains the previous playitem ID.
                 */
                PbcRegGetPSR(PLAYCTRL_PSR_PLAYITEM, &uiPrevPlayitemID);
                uiPrevPlayitemID &= 0x0000ffff;

                /* get stream path that primary audio is on */
                stream_path = PbcPLCtrlGetDRStreamType(hPBC, PBC_STREAM_ENTRY_PAUDIO, pPIContext->uiPlayitemID,
                    pPIContext->StreamInfo.uiPrimaryAudioStn);

                /* Only configure primary audio if it is on the main */
                if (DR_STREAM_MAIN == stream_path)
                {
                    /* Configure Primary Audio */
                    if (PbcPLCtrlConfigPrimaryAudio(hPBC, uiPlaylistID, pPIContext->uiPlayitemID,
                        pPIContext->StreamInfo.uiPrimaryAudioStn) != PLAYCTRL_SUCCESS)
                    {
                        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: pbcplctrlSelectPrimaryAudio() FAILED!\n"));
                    }
                }
                else if (DR_STREAM_NONE == stream_path)
                {
                    /* There is no audio, so remove the audio demux */
                    if (PbcPLCtrlConfigPrimaryAudio(hPBC, uiPlaylistID, pPIContext->uiPlayitemID, 0) != PLAYCTRL_SUCCESS)
                    {
                        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: pbcplctrlSelectPrimaryAudio() FAILED!\n"));
                    }
                }

                /* get stream path that secondary audio is on */
                stream_path = PbcPLCtrlGetDRStreamType(hPBC, PBC_STREAM_ENTRY_SAUDIO, pPIContext->uiPlayitemID,
                    pPIContext->StreamInfo.uiSecondaryAudioStn);

                /* Only configure secondary audio if it is on the main */
                if (DR_STREAM_MAIN == stream_path)
                {
                    /* Configure Secondary Audio */
                    if (pbcplctrlConfigSecondaryAudio(hPBC, uiPlaylistID, pPIContext->uiPlayitemID,
                        pPIContext->StreamInfo.uiSecondaryAudioStn) != PLAYCTRL_SUCCESS)
                    {
                        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: pbcplctrlSelectPrimaryAudio() FAILED!\n"));
                    }
                }

                /* get stream path that pg/textst is on */
                stream_path = PbcPLCtrlGetDRStreamType(hPBC, PBC_STREAM_ENTRY_PGTEXTST, pPIContext->uiPlayitemID,
                    pPIContext->StreamInfo.uiPGTextSTStn);

                /*
                 * Only configure PG/TextST if there is no pg/textst stream (to remove demux), or
                 * if the stream is on the main path.
                 */
                if ( (DR_STREAM_MAIN == stream_path) || (DR_STREAM_NONE == stream_path) )
                {
                    /* Configure PG and Text ST */
                    if (PbcPLCtrlConfigPGandTextST(hPBC, uiPlaylistID, pPIContext->uiPlayitemID,
                        pPIContext->StreamInfo.uiPGTextSTStn) != PLAYCTRL_SUCCESS)
                    {
                        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: PbcPLCtrlConfigPGandTextST() FAILED!\n"));
                    }
                }
                else
                {
                    /*
                     * Subtitle is out-of-mux TextST on a subpath.  Now we need to determine if
                     * this TextST subpath has already been preloaded or not.  If it has not already
                     * been preloaded, then we should preload it now.  If it has been preloaded, then
                     * we don't need to do anything.  Note that we cannot preload out-of-mux streams
                     * whenever we send the next playitem to the DR because that would cause the preload
                     * buffer to be filled with the stream for the next playitem, not the current one.
                     */

                    /*
                     * Need to know if the new textst stream entry uses the same clip as the previous
                     * textst stream entry.  If they do not use the same clip, then we need to preload
                     * the new textst subpath.
                     */
                    if (FALSE == pbcPLCtrlIsSameClip(hPBC, PBC_STREAM_ENTRY_PGTEXTST, pPIContext->uiPlayitemID, (uint16)(pPIContext->StreamInfo.uiPGTextSTStn),
                                                     (uint16)(uiPrevPlayitemID), (uint16)(uiLastSubtitleStn)) )
                    {
                        /*
                         * Enable DR queue on TextST stream.
                         * Must do this before preloading the clip, because the clip is prefilled synchronously.
                         * If DR queue was not enabled whenever we started to prefill, we would wait forever
                         * because DR would never start streaming data to the PE.
                         */
                        DRQueueControl(hPBC->hDR, DR_STREAM_BDROM_SUBPATH_TEXT_SUBTITLE, DR_QUEUE_CMD_ENABLE);

                        /* Preload the new TextST, and wait for prefill to complete */
                        if (PbcPLCtrlPlaySubPlayitem(hPBC, pPIContext->uiPlayitemID, PBC_STREAM_ENTRY_PGTEXTST, pPIContext->StreamInfo.uiPGTextSTStn, TRUE) != PLAYCTRL_SUCCESS)
                        {
                            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: Failed to play subplayitem!\n"));
                        }
                    }
                }

                /* get stream path that IG is on */
                stream_path = PbcPLCtrlGetDRStreamType(hPBC, PBC_STREAM_ENTRY_IG, pPIContext->uiPlayitemID,
                    pPIContext->StreamInfo.uiIGStn);

                /*
                 * Only configure IG if there is no IG stream (to remove demux), or
                 * if the stream is on the main path.
                 */
                if ( (DR_STREAM_MAIN == stream_path) || (DR_STREAM_NONE == stream_path) )
                {
                    /* Configure IG */
                    if (PbcPLCtrlConfigIG(hPBC, uiPlaylistID, pPIContext->uiPlayitemID,
                        pPIContext->StreamInfo.uiIGStn) != PLAYCTRL_SUCCESS)
                    {
                        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: PbcPLCtrlConfigIG() FAILED!\n"));
                    }
                }
                else
                {
                    /*
                     * IG is out-of-mux on a subpath.  Now we need to determine if
                     * this IG subpath has already been preloaded or not.  If it has not already
                     * been preloaded, then we should preload it now.  If it has been preloaded, then
                     * we don't need to do anything.  Note that we cannot preload out-of-mux streams
                     * whenever we send the next playitem to the DR because that would cause the preload
                     * buffer to be filled with the stream for the next playitem, not the current one.
                     */

                    /*
                     * Need to know if the new IG stream entry uses the same clip as the previous
                     * IG stream entry.  If they do not use the same clip, then we need to preload
                     * the new IG subpath.
                     */
                    if (FALSE == pbcPLCtrlIsSameClip(hPBC, PBC_STREAM_ENTRY_IG, pPIContext->uiPlayitemID, (uint16)(pPIContext->StreamInfo.uiIGStn),
                                                     (uint16)(uiPrevPlayitemID), (uint16)(uiLastIGStn)) )
                    {
                        ULONG   out_msg[4];

                        /* Notify UI that we are preloading an out of mux IG stream since this can
                         * take some time to prefill. */
                        out_msg[0] = VDVD_STATUS_LOADING;
                        out_msg[1] = VDVD_LOADING_TITLE;
                        UsrEventHandler(out_msg);

                        /*
                         * Enable DR queue on IG stream.
                         * Must do this before preloading the clip, because the clip is prefilled synchronously.
                         * If DR queue was not enabled whenever we started to prefill, we would wait forever
                         * because DR would never start streaming data to the PE.
                         */
                        DRQueueControl(hPBC->hDR, DR_STREAM_BDROM_SUBPATH_INTERACTIVE_GRAPHICS, DR_QUEUE_CMD_ENABLE);

                        /* Preload the new IG, and wait for prefill to complete */
                        if (PbcPLCtrlPlaySubPlayitem(hPBC, pPIContext->uiPlayitemID, PBC_STREAM_ENTRY_IG, pPIContext->StreamInfo.uiIGStn, TRUE) != PLAYCTRL_SUCCESS)
                        {
                            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: Failed to play subplayitem!\n"));
                        }

                        /* Notify UI that we are done preloading the IG */
                        out_msg[0] = VDVD_STATUS_LOAD_COMPLETE;
                        out_msg[1] = VDVD_LOADING_TITLE;
                        UsrEventHandler(out_msg);
                    }
                }
            }
        }

        time45k_StartTime = (!hPBC->fReverse) ? pPIContext->ptsInTime : pPIContext->ptsOutTime;

        PbcPLCtrlUpdateLocation(hPBC, time45k_StartTime, TRUE);


        /* Get the Current PE PlayRate configuration */
        PEiStreamCtrlGetRate(hPBC->hPE, &OldPlayRate);

        /* set the new PE decode rate */
        if ( (pPIContext->PlayRate.rate != OldPlayRate.rate) &&
             (hPBC->tState == PLAYCTRL_STATE_PLAY          )  )
        {
            PEiStreamCtrlSetRate(hPBC->hPE, &(pPIContext->PlayRate));
        }

        /***                                           ***/
        /***   PUT NEXT PLAYITEM INTO THE PLAY QUEUE   ***/
        /***                                           ***/
        /***   this section puts the next play item    ***/
        /***    into the play queue                    ***/


        /* Get the next playitem id */
        uiNextPlayitemID = PbcPLCtrlGetNextPlayitem(hPBC, pPIContext->uiPlayitemID);

        /*
         * If the the next playitem exists, then configure the DR to
         * start reading the clip(s) for the next playitem.
         */
        if (uiNextPlayitemID != INVALID_PLAYITEM)
        {
            PLAYITEM *pNextPlayItem      = NULL;
            UBYTE    ubNextRandomShuffle = 0xff;
            BOOLEAN  fReverse            = hPBC->fReverse;
            uint32   uiPlayRate          = hPBC->ulPlayRate;
            VDVD_CONNECT_COND connection;

            /* get the playitem info */
            if (MPLSGetPlayItem(uiNextPlayitemID, &pNextPlayItem) != MPLS_SUCCESS)
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: Failed to get playitem!\n"));
                goto errout;
            }

            time45k_StartTime = (!hPBC->fReverse) ? pNextPlayItem->IN_time : pNextPlayItem->OUT_time;

            if ( (pPLAppInfo->PlayList_playback_type == MPLS_RANDOM_PLAYLIST) ||
                (pPLAppInfo->PlayList_playback_type == MPLS_SHUFFLE_PLAYLIST) )
            {
                /* Get the next random/shuffle index */

⌨️ 快捷键说明

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