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

📄 pbc_pbscenario.cpp

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

    /* If playlist playback is active, stop playback */
    if (hPBC->tState != PLAYCTRL_STATE_STOP)
    {
        /* stop the playlist */
        if (PbcPLCtrlStopPL(hPBC, FALSE) != PLAYCTRL_SUCCESS)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioStop: Failed to stop playlist\n"));
            return (PLAYCTRL_FAILURE);
        }

        /* enter stop state */
        hPBC->tState        = PLAYCTRL_STATE_STOP;
        hPBC->ulPlayRate    = 0;

        /* flush the input queue to remove any PE/DR events from the previous playback */
        PbcEngineClearCmdQueue(hPBC);
    }

    return (PLAYCTRL_SUCCESS);
}

/**
 * PbcPbScenarioSuspend -- Suspend playback of a playlist.  State information of
 *                    playlist should be stored in backup registers.
 *
 * @param
 *      hPBC -- handle to playback control engine private data
 *      data1 -- not used
 *      data2 -- not used
 *      data3 -- not used
 *
 * @retval
 *      PLAYCTRL_STATUS
 */
PLAYCTRL_STATUS PbcPbScenarioSuspend(PBC_HANDLE *hPBC, ULONG data1, ULONG data2, ULONG data3)
{
    APPINFOPLAYLIST_TABLE   *pAppInfoPL = NULL;

    DBGPRINT(DBG_ON(DBG_TRACE), ("PbcPbScenarioSuspend: ENTER\n"));

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

    /*
     * If playlist playback is active, suspend the pbc engine.
     */
    if (hPBC->tState != PLAYCTRL_STATE_STOP)
    {
        /* Get playlist info */
        if (MPLSGetAppInfo(&pAppInfoPL) != MPLS_SUCCESS)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioSuspend: Failed to get playlist info!\n"));
            return (PLAYCTRL_FAILURE);
        }

        /* If playlist is random/shuffle playback type, then backup random/shuffle status */
        if ( (pAppInfoPL->PlayList_playback_type == MPLS_RANDOM_PLAYLIST) ||
            (pAppInfoPL->PlayList_playback_type == MPLS_SHUFFLE_PLAYLIST) )
        {
            PbcPLCtrlBackupRandomShuffle();
        }

        /* flush the input queue to remove any PE/DR events from the previous playback */
        PbcEngineClearCmdQueue(hPBC);

        /* Take register mutex semaphore */
        OS_SemTake(hPBC->semRegisterMutex, OS_WAIT_FOREVER);

        /* store backup registers */
        hPBC->fBackupValid = TRUE;
        PbcRegStoreBackup();

        /* Give register mutex semaphore */
        OS_SemGive(hPBC->semRegisterMutex);

        /* stop the playlist */
        if (PbcPLCtrlStopPL(hPBC, TRUE) != PLAYCTRL_SUCCESS)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioSuspend: Failed to stop playlist\n"));
            return (PLAYCTRL_FAILURE);
        }

        /* Set state to stopped */
        hPBC->tState = PLAYCTRL_STATE_STOP;
    }
    else
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioSuspend: PBC Engine is stopped!\n"));
        return (PLAYCTRL_FAILURE);
    }

    return (PLAYCTRL_SUCCESS);
}

/**
 * PbcPbScenarioResume -- Resume playback of a suspended playlist.  State information
 *                   of suspended playlist should be loaded from backup registers.
 *
 *
 * @param
 *      hPBC -- handle to playback control engine private data
 *      data1 -- not used
 *      data2 -- not used
 *      data3 -- not used
 *
 * @retval
 *      PLAYCTRL_STATUS
 */
PLAYCTRL_STATUS PbcPbScenarioResume(PBC_HANDLE *hPBC, ULONG data1, ULONG data2, ULONG data3)
{
    uint32                  uiPlaylistID;
    uint32                  uiPlayitemID;
    uint32                  uiPresTime;
    APPINFOPLAYLIST_TABLE   *pAppInfoPL     = NULL;
    UBYTE                   ubRandomShuffle = 0xff;
    uint32                  uiLastPlaylistID;
    BOOLEAN                 fNewPlaylist;
    PE_ISTREAMCTRL_STATE    tPEState;

    DBGPRINT(DBG_ON(DBG_TRACE), ("PbcPbScenarioResume: ENTER\n"));

    if (hPBC == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioResume: playback control engine not created!\n"));
        return (PLAYCTRL_FAILURE);
    }

    /* Backup registers must be valid in order to resume */
    if (hPBC->fBackupValid == TRUE)
    {
        /*
         * If playlist playback is active, then stop pbc engine first.
         */
        if (hPBC->tState != PLAYCTRL_STATE_STOP)
        {
            /* stop the playlist */
            if (PbcPLCtrlStopPL(hPBC, TRUE) != PLAYCTRL_SUCCESS)
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioResume: Failed to stop playlist\n"));
                return (PLAYCTRL_FAILURE);
            }

            /* Enter stop state */
            hPBC->tState = PLAYCTRL_STATE_STOP;

            /* flush the input queue to remove any PE/DR events from the previous playback */
            PbcEngineClearCmdQueue(hPBC);
        }

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

        /* Take register mutex semaphore */
        OS_SemTake(hPBC->semRegisterMutex, OS_WAIT_FOREVER);

        /* Load backup registers */
        PbcRegLoadBackup();
        hPBC->fBackupValid = FALSE;

        /* Get the playlist, playitem, and presentation time register values */
        PbcRegGetPSR(PLAYCTRL_PSR_PLAYLIST,  &uiPlaylistID);
        PbcRegGetPSR(PLAYCTRL_PSR_PLAYITEM,  &uiPlayitemID);
        PbcRegGetPSR(PLAYCTRL_PSR_PRES_TIME, &uiPresTime);

        /* Give register mutex semaphore */
        OS_SemGive(hPBC->semRegisterMutex);

        /* Pull out playlist id and playitem id from register values */
        uiPlaylistID &= 0x0000ffff;
        uiPlayitemID &= 0x0000ffff;

        /* Load the playlist */
        MPLSLoad(uiPlaylistID);

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

        /* If playlist is random/shuffle playback type, then restore random/shuffle status */
        if ( (pAppInfoPL->PlayList_playback_type == MPLS_RANDOM_PLAYLIST) ||
            (pAppInfoPL->PlayList_playback_type == MPLS_SHUFFLE_PLAYLIST) )
        {
            PbcPLCtrlRestoreRandomShuffle();
            ubRandomShuffle = PbcPLCtrlGetRandomShuffleIndex(hPBC);
        }

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

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

        /*
         * Start the playlist from the playitem and time where is was suspended.
         */
        if (PbcPLCtrlStartPL(hPBC, uiPlaylistID, (uint16)(uiPlayitemID), uiPresTime, ubRandomShuffle, fNewPlaylist) != PLAYCTRL_SUCCESS)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioResume: pbcpbscenarioPlayPL() FAILED!\n"));
            return (PLAYCTRL_FAILURE);
        }

        /* Update Playback Control Engine State */
        hPBC->tState = PLAYCTRL_STATE_PLAY;
    }
    else
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioResume: Backup registers not valid!\n"));
        return (PLAYCTRL_FAILURE);
    }

    return (PLAYCTRL_SUCCESS);
}

/**
 * PbcPbScenarioSkipNext -- Start playback at next skip point in the playlist.
 *
 * @param
 *      hPBC -- handle to playback control engine private data
 *      data1 -- not used
 *      data2 -- not used
 *      data3 -- not used
 *
 * @retval
 *      PLAYCTRL_STATUS
 */
PLAYCTRL_STATUS PbcPbScenarioSkipNext(PBC_HANDLE *hPBC, ULONG data1, ULONG data2, ULONG data3)
{
    APPINFOPLAYLIST_TABLE   *pAppInfoPlayList       = NULL;
    PLAYLISTMARK_TABLE      *pPLMark                = NULL;
    BOOLEAN                 fMarkFound              = FALSE;
    uint16                  uiCount                 = 0;
    PLAYITEM                *pPlayitem              = NULL;
    UBYTE                   ubRandomShuffleIndex    = 0xff;
    TIME45k                 time45k_CurrPTS;
    uint32                  uiPlayitemID;
    uint16                  uiTargetMarkID;
    uint16                  uiPlaymarkID            = 0;
    uint32                  *pOutMarkNumber         = (uint32 *)data1;
    uint8                   uiMarkType              = (uint8)data2;

    DBGPRINT(DBG_ON(DBG_TRACE), ("PbcPbScenarioSkipNext: ENTER\n"));

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

    /* If playlist playback is not active this operation is not allowed */
    if (hPBC->tState == PLAYCTRL_STATE_STOP)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioSkipNext: not playing!\n"));
        return (PLAYCTRL_FAILURE);
    }

    OS_SemTake(hPBC->semRegisterMutex, OS_WAIT_FOREVER);

    /* Get the playitem and presentation time player registers */
    PbcRegGetPSR(PLAYCTRL_PSR_PLAYITEM, &uiPlayitemID);
    PbcRegGetPSR(PLAYCTRL_PSR_PRES_TIME, &time45k_CurrPTS);
    uiPlayitemID &= 0x0000ffff;

    OS_SemGive(hPBC->semRegisterMutex);

    /* get the playlist info */
    MPLSGetAppInfo(&pAppInfoPlayList);

    /* Get playlist mark from database */
    MPLSGetPlayMark(&pPLMark);

    /* Set target entry mark */
    uiTargetMarkID = (uint16)(PbcPLCtrlCalculatePLMark(pPLMark, (uint16)(uiPlayitemID), time45k_CurrPTS, uiMarkType) + 1);

    /*
     * Look for appropriate mark.
     */
    for (uint16 i = 0; i < pPLMark->number_of_PlayList_marks; i++)
    {
        /*
         * If this mark has the mark type we want, then increase count.
         */
        if (pPLMark->PL_mark[i].mark_type & uiMarkType)
        {
            uiCount++;
        }

        /*
         * If this mark is the mark we are looking for, then
         * keep track of the mark ID, and finish search.
         */
        if (uiCount == (uiTargetMarkID + 1)) // marks start from 0
        {
            fMarkFound = TRUE;
            uiPlaymarkID = i;
            break;
        }
    }

    /*
     * If current playlist is random/shuffle, then we need to make sure that the playmark
     * found is in the current playitem.  If it is not in the current playitem, then we need
     * to transition to a new playitem, which will be the next playitem on the random/shuffle list.
     */
    if ( (pAppInfoPlayList->PlayList_playback_type == MPLS_RANDOM_PLAYLIST) ||
         (pAppInfoPlayList->PlayList_playback_type == MPLS_SHUFFLE_PLAYLIST) )
    {
        /* get random/shuffle index for current playitem */
        ubRandomShuffleIndex = PbcPLCtrlGetRandomShuffleIndex(hPBC);

        /* If playmark is not in current playitem, need to transition to another playitem */
        if ( (fMarkFound == FALSE) || (uiPlayitemID != pPLMark->PL_mark[uiPlaymarkID].ref_to_PlayItem_id) )
        {
            uint16 uiNextPI;

            /* Reset flag */
            fMarkFound = FALSE;

            /* Get the next playitem in random/shuffle list */
            uiNextPI = PbcPLCtrlGetNextPlayitem(hPBC, uiPlayitemID);

            /* Check that next playitem is valid */
            if ( (uiNextPI == INVALID_PLAYITEM) || (ubRandomShuffleIndex == 0xff) )
            {
                DBGPRINT(DBG_ON(DBG_TRACE), ("PbcPbScenarioSkipNext: No more marks in random/shuffle playlist!\n"));
            }
            else
            {
                /* Increment random shuffle index */
                ubRandomShuffleIndex++;

                /*
                 * Look for first mark in next playitem.
                 */
                for (uint16 i = 0; i < pPLMark->number_of_PlayList_marks; i++)
                {
                    /*
                     * If this mark has mark type we want and it is in the desired playitem, we're done.
                     */
                    if ( (pPLMark->PL_mark[i].mark_type & uiMarkType) && (pPLMark->PL_mark[i].ref_to_PlayItem_id == uiNextPI) )
                    {
                        fMarkFound = TRUE;
                        uiPlaymarkID = i;
                        break;
                    }
                }
            }

⌨️ 快捷键说明

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