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

📄 pbc_pbscenario.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                return (PLAYCTRL_SUCCESS);
            }
            else
            {
                PbcPLCtrlInitRandomShuffle();
                ubRandomShuffle = 0;
            }
        }

        /* Get PSR for current playitem id */
        PbcRegGetPSR(PLAYCTRL_PSR_PLAYITEM, &uiPlayitemID);

        /* Pull out current playitem id from PSR value */
        uiPlayitemID &= 0x0000ffff;

        /* Get the playitem info for target playitem */
        if (MPLSGetPlayItem(pPLMark->PL_mark[uiTargetPM].ref_to_PlayItem_id, &pPlayitem) != MPLS_SUCCESS)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioPlayPLMark: Failed to get playitem info\n"));
            return (PLAYCTRL_FAILURE);
        }

        /* Get ID of last playlist to be played */
        PbcRegGetPSR(PLAYCTRL_PSR_PLAYLIST, &uiLastPlaylistID);

        /* Get the PE run state */
        PEiStreamCtrlGetState(hPBC->hPE, &tPEState);

        /* Determine if this is a new playlist */
        fNewPlaylist = (uiLastPlaylistID != uiPlaylistID) || (tPEState != PE_ISTREAMCTRL_STATE_RUN);

        /*
         * If this is UO and the playitem's random access flag is set, then cannot allow access into
         * the playitem and must start from the beginning of the playitem.
         */
        if ( (fIsUserOp == TRUE) && (pPlayitem->PlayItem_random_access_flag == 1) )
        {
            DBGPRINT(DBG_ON(DBG_TRACE), ("PbcPbScenarioPlayPLMark: Playitem Random Access flag is set, so playing from beginning of playitem!\n"));

            /*
             * Start the playlist at the beginning of the playitem
             */
            if (PbcPLCtrlStartPL(hPBC, uiPlaylistID, pPLMark->PL_mark[uiTargetPM].ref_to_PlayItem_id,
                                 pPlayitem->IN_time, ubRandomShuffle, fNewPlaylist) != PLAYCTRL_SUCCESS)
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioPlayPLMark: pbcpbscenarioPlayPL() FAILED!\n"));
                return (PLAYCTRL_FAILURE);
            }
        }
        else
        {
            /*
             * Start the playlist at the specified time in the playitem that
             * the mark is located in.
             */
            if (PbcPLCtrlStartPL(hPBC, uiPlaylistID, pPLMark->PL_mark[uiTargetPM].ref_to_PlayItem_id,
                                 pPLMark->PL_mark[uiTargetPM].mark_time_stamp, ubRandomShuffle, fNewPlaylist) != PLAYCTRL_SUCCESS)
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioPlayPLMark: pbcpbscenarioPlayPL() FAILED!\n"));
                return (PLAYCTRL_FAILURE);
            }
        }

        /* Update Playback Control Engine State */
        hPBC->tState = PLAYCTRL_STATE_PLAY;
    }
    else
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioPlayPLMark: specified entry mark not found!\n"));
        return (PLAYCTRL_FAILURE);
    }

    return (PLAYCTRL_SUCCESS);
}

/**
 * PbcPbScenarioLinkMark -- Change playback position to the specified playmark.
 *
 * @param
 *      hPBC -- handle to playback control engine private data
 *      data1 -- playmark number
 *      data2 -- indicates user op or navigation command
 *      data3 -- indicates if mark to be linked to is a repeat mark.  If this flag
 *               is set, the first 2 parameters are ignored and the playitem and time
 *               in the repeat block are used as the link point.
 *
 * @retval
 *      PLAYCTRL_STATUS
 */
PLAYCTRL_STATUS PbcPbScenarioLinkMark(PBC_HANDLE *hPBC, ULONG data1, ULONG data2, ULONG data3)
{
    uint32                  uiPlaymarkID    = data1;
    BOOLEAN                 fIsUserOp       = (BOOLEAN)(data2);
    PLAYLISTMARK_TABLE      *pPLMark        = NULL;
    APPINFOPLAYLIST_TABLE   *pAppInfoPL     = NULL;
    BOOLEAN                 fMarkFound      = FALSE;
    uint32                  uiCount         = 0;
    uint32                  uiTargetPM      = 0;
    BOOLEAN                 fRepeatMark     = (BOOLEAN)(data3);

    DBGPRINT(DBG_ON(DBG_TRACE), ("PbcPbScenarioLinkMark: playmark %lu\n", uiPlaymarkID));

    /* check for valid handle */
    if (hPBC == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioLinkMark: NULL handle!\n"));
        return (PLAYCTRL_NULL_POINTER);
    }

    /* Check that playback is active */
    if (hPBC->tState == PLAYCTRL_STATE_STOP)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioLinkMark: Playback is stopped!\n"));
        return (PLAYCTRL_FAILURE);
    }

    /*
     * If this is a link to a repeat mark, then link to the playitem and time
     * defined in the repeat block, and return.
     */
    if (fRepeatMark == TRUE)
    {
        /* check that repeat mode is on */
        if (hPBC->RepeatBlock.repeat_mode == VDVD_INFO_REPEAT_OFF)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioLinkMark: Repeat mode is off!\n"));
            return (PLAYCTRL_FAILURE);
        }

        /* if a is only set, force the AB point set and tell the PSL about it */
        if (hPBC->RepeatBlock.repeat_mode == VDVD_INFO_REPEAT_A)
        {
            uint32 uiRepeatWindow;
            uint32 uiPlayitemID;
            TIME45k time45k_CurrPTS;
            PLAYITEM  *pPlayitem  = NULL;

            /* Get current playitem */
            PbcRegGetPSR(PLAYCTRL_PSR_PLAYITEM, &uiPlayitemID);
            uiPlayitemID &= 0x0000ffff;

            /* Get current pts */
            PbcRegGetPSR(PLAYCTRL_PSR_PRES_TIME, &time45k_CurrPTS);

            /* Calculate the repeat window size */
            if (uiPlayitemID == hPBC->RepeatBlock.uiPlayitemID_IN)
            {
                /*
                 * Repeat start/end points are in same playitem, so the repeat window
                 * is just the difference in pts's.
                 */
                uiRepeatWindow = (time45k_CurrPTS - hPBC->RepeatBlock.time45k_IN) / 45000;
            }
            else
            {
                /*
                 * Repeat start/end points are NOT in same playitem, so more detailed
                 * calculation needs to be done:
                 * Window Size = Time from starting pts to end of starting playitem +
                 *               Total time of playitems between start/end playitems +
                 *               Time from start of end playitem to end pts
                 */

                /* Get the playitem info for repeat starting playitem */
                if (MPLSGetPlayItem((uint16)(hPBC->RepeatBlock.uiPlayitemID_IN), &pPlayitem) != MPLS_SUCCESS)
                {
                    DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioRepeeat: Failed to get playitem info\n"));
                    return (PLAYCTRL_FAILURE);
                }

                /* set repeat window to time from repeat start pts to end of the repeat start playitem */
                uiRepeatWindow = (pPlayitem->OUT_time - hPBC->RepeatBlock.time45k_IN) / 45000;

                /*
                 * Increment repeat window by playitem time of each playitem between repeat
                 * starting playitem and repeat ending playitem.
                 */
                for (uint16 i = (uint16)(hPBC->RepeatBlock.uiPlayitemID_IN + 1); i < uiPlayitemID; i++)
                {
                    /* Get the playitem info */
                    if (MPLSGetPlayItem(i, &pPlayitem) != MPLS_SUCCESS)
                    {
                        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioRepeeat: Failed to get playitem info\n"));
                        return (PLAYCTRL_FAILURE);
                    }

                    uiRepeatWindow += (pPlayitem->OUT_time - pPlayitem->IN_time) / 45000;
                }

                /* Get the playitem info for repeat ending playitem */
                if (MPLSGetPlayItem((uint16)(uiPlayitemID), &pPlayitem) != MPLS_SUCCESS)
                {
                    DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioRepeeat: Failed to get playitem info\n"));
                    return (PLAYCTRL_FAILURE);
                }

                /* increment repeat window by time from start of repeat end playitem to repeat end pts */
                uiRepeatWindow += (time45k_CurrPTS - pPlayitem->IN_time ) / 45000;
            }

            /* Set repeat end point */
            hPBC->RepeatBlock.uiPlayitemID_OUT  = uiPlayitemID;
            hPBC->RepeatBlock.time45k_OUT       = time45k_CurrPTS;

            /* Set repeat mode */
            hPBC->RepeatBlock.repeat_mode = VDVD_INFO_REPEAT_AB;

            /* send message to the PSL */
            ULONG message[4] = {0};
            message[0] = VDVD_STATUS_A_B;
            UsrEventHandler(message);
        }

        /* Link to repeat start point */
        if (pbcpbscenarioLink(hPBC, hPBC->RepeatBlock.uiPlayitemID_IN, hPBC->RepeatBlock.time45k_IN, 0, TRUE) != PLAYCTRL_SUCCESS)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioLinkMark: pbcpbscenarioLink() FAILED!\n"));
            return (PLAYCTRL_FAILURE);
        }

        return (PLAYCTRL_SUCCESS);
    }

    /* Get playlist info */
    if (MPLSGetAppInfo(&pAppInfoPL) != MPLS_SUCCESS)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioLinkMark: Failed to get playlist info!\n"));
        return (PLAYCTRL_FAILURE);
    }

    /* Get playlist mark from database */
    if (MPLSGetPlayMark(&pPLMark) != MPLS_SUCCESS)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioLinkMark: MPLSGetPlayMark() FAILED!\n"));
        return (PLAYCTRL_FAILURE);
    }

    /*
     * If this is a user operation and playback type is random/shuffle, then
     * the operation is invalid.
     */
    if ( (pAppInfoPL->PlayList_playback_type == MPLS_SEQUENTIAL_PLAYLIST) || (fIsUserOp == FALSE) )
    {
        /*
         * Look for appropriate entry mark.
         */
        for (uint16 i = 0; i < pPLMark->number_of_PlayList_marks; i++)
        {
            /*
             * If this mark is an entry-mark, then increase count.
             */
            if (pPLMark->PL_mark[i].mark_type == ENTRY_MARK)
            {
                uiCount++;
            }
            else
            {
                /* if this is a navigation command and an link point, then increase count */
                if ( (fIsUserOp == FALSE) && (pPLMark->PL_mark[i].mark_type == LINK_POINT) )
                {
                    uiCount++;
                }
            }

            /*
             * If this mark is the entry mark we are looking for, then
             * keep track of the mark ID, and finish search.
             */
            if (fIsUserOp == TRUE)
            {
                if (uiCount == uiPlaymarkID)
                {
                    fMarkFound = TRUE;
                    uiTargetPM = i;
                    break;
                }
            }
            else if (i == uiPlaymarkID)
            {
                fMarkFound = TRUE;
                uiTargetPM = i;
                break;
            }
        }
    }
    else
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioLinkMark: Operation invalid!\n"));
        return (PLAYCTRL_FAILURE);
    }

    /*
     * If a specified mark exists, then change playback to the mark.
     * Otherwise, fail this operations.
     */
    if (fMarkFound == TRUE)
    {
        PLAYITEM    *pPlayitem  = NULL;
        uint32      uiPlayitemID;

        /* Get PSR for current playitem id */
        PbcRegGetPSR(PLAYCTRL_PSR_PLAYITEM, &uiPlayitemID);
        uiPlayitemID &= 0x0000ffff;

        /* Get the playitem info for target playitem */
        if (MPLSGetPlayItem(pPLMark->PL_mark[uiTargetPM].ref_to_PlayItem_id, &pPlayitem) != MPLS_SUCCESS)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioLinkMark: Failed to get playitem info\n"));
            return (PLAYCTRL_FAILURE);
        }

        /*
         * If this is UO and the playitem's random access flag is set, then cannot allow access into
         * the playitem and must start from the beginning of the playitem.
         */
        if ( (fIsUserOp == TRUE) && (pPlayitem->PlayItem_random_access_flag == 1) )
        {
            DBGPRINT(DBG_ON(DBG_TRACE), ("PbcPbScenarioLinkMark: Playitem Random Access flag is set, so linking to beginning of playitem!\n"));

            /*
             * Link to beginning of playitem
             */
            if (pbcpbscenarioLink(hPBC, pPLMark->PL_mark[uiTargetPM].ref_to_PlayItem_id, pPlayitem->IN_time, 0) != PLAYCTRL_SUCCESS)
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioLinkMark: pbcpbscenarioLink() FAILED!\n"));
                return (PLAYCTRL_FAILURE);
            }
        }
        else
        {
            /*
             * Link to the specified time in the playitem that
             * the mark is located in.
             */
            if (pbcpbscenarioLink(hPBC, pPLMark->PL_mark[uiTargetPM].ref_to_PlayItem_id,
                                  pPLMark->PL_mark[uiTargetPM].mark_time_stamp, 0) != PLAYCTRL_SUCCESS)
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioLinkMark: pbcpbscenarioLink() FAILED!\n"));
                return (PLAYCTRL_FAILURE);
            }
        }

        /* 
         * Do this after doing the link to be sure any previously playing clip is flushed out
         * before resetting the mark id.  There was a bug when we were setting this value before 
         * doing the link because we were resetting this mark id, then there was a vsync from the 
         * currently playing clip so we were detecting a change in playmark from the vsync, so 
         * incorrectly sent a playmark change event.  Setting this valua fter the link will prevent
         * this error from happening.  There will not be a race condition here because the first
         * vsync will not happen until after the beginning of stream for this new clip, and 
         * the beginning of stream happens in context of the pbc engine task, so we are safe.
         */

        /*
         * Set playmark id to an invalid value so that we will detect a change in playmark id

⌨️ 快捷键说明

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