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

📄 pbc_plcontrol.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                    /* Set repeat in progress flag */
                    hPBC->RepeatBlock.fRepeatInProgress = TRUE;

                    /*
                     * Process the link to repeat starting point in the pbc engine task.
                     */
                    if (PbcEngineProcessCmd(hPBC, PLAYCTRL_LINKMARK, 0, 0, TRUE, FALSE) != PLAYCTRL_SUCCESS)
                    {
                        DbgPrint(("%s: pbc engine failed to process link!\n", __FUNCTION__));
                        goto errout;
                    }
                }
                else
                {
                    /*
                     * If playlist playback is active then stop the pbc engine.
                     */
                    if (hPBC->tState != PLAYCTRL_STATE_STOP)
                    {
                        /* stop the playlist */
                        if (PbcPLCtrlStopPL(hPBC, TRUE) != PLAYCTRL_SUCCESS)
                        {
                            DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Failed to stop playlist\n", __FUNCTION__));
                            goto errout;
                        }

                        /* enter the stop state */
                        hPBC->tState = PLAYCTRL_STATE_STOP;
                    }

                    /* get the playitem info */
                    if (MPLSGetPlayItem(pPIContext->uiPlayitemID, &pPlayItem) != MPLS_SUCCESS)
                    {
                        DBGPRINT(DBG_ON(DBG_ERROR), ("%s:%u - MPLSGetPlayItem: Failed to get playitem!\n", __FILE__, __LINE__));
                        goto errout;
                    }

                    if (PbcPLCtrlStartPL(hPBC, uiPlaylistID, pPIContext->uiPlayitemID, pPlayItem->IN_time, 0, FALSE) != PLAYCTRL_SUCCESS)
                    {
                        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlEndStream: PbcPLCtrlStartPL() FAILED!\n"));
                        return (PLAYCTRL_FAILURE);
                    }

                    hPBC->tState = PLAYCTRL_STATE_PLAY;
                }
            }
        }
        else
        {
            /* Get the next playitem id */
            uiNextPlayitemID = PbcPLCtrlGetNextPlayitem(hPBC, pPIContext->uiPlayitemID);

            /*
             * If the current playitem is the last playitem, then this is the end of a playlist.
             */
            if (uiNextPlayitemID == INVALID_PLAYITEM)
            {
                DBGPRINT(DBG_ON(DBG_TRACE), ("PbcPLCtrlEndStream for PI: %u - played to end of playlist\n", pPIContext->uiPlayitemID));

                /*
                 * If repeat mode is on then link to the repeat start point, rather than
                 * ending the playlist.
                 */
                if ( (hPBC->RepeatBlock.repeat_mode != VDVD_INFO_REPEAT_OFF) && (hPBC->RepeatBlock.fRepeatInProgress == FALSE) )
                {
                    /* Set repeat in progress flag */
                    hPBC->RepeatBlock.fRepeatInProgress = TRUE;

                    /*
                     * Process the link to repeat starting point in the pbc engine task.
                     */
                    if (PbcEngineProcessCmd(hPBC, PLAYCTRL_LINKMARK, 0, 0, TRUE, FALSE) != PLAYCTRL_SUCCESS)
                    {
                        DbgPrint(("%s: pbc engine failed to process link!\n", __FUNCTION__));
                        goto errout;
                    }
                }
                else
                {
                    /*
                     * If waiting on a still, then set flag to indicate the playlist playback
                     * should complete when the still expires.
                     * Otherwise, terminate playlist playback.
                     */
                    if (hPBC->ulStillTime != 0)
                    {
                        /* Pending playlist complete */
                        hPBC->fPLCompletePending = TRUE;
                    }
                    else
                    {
                        /*
                         * Playlist complete
                         */
                        PbcPLCtrlPlaylistComplete(hPBC, FALSE);
                    }
                }
            }
        }
    }
    return (PLAYCTRL_SUCCESS);

errout:

    /* playlist complete */
    PbcPLCtrlPlaylistComplete(hPBC, TRUE);

    return (PLAYCTRL_FAILURE);
}

/**
 * PbcPLCtrlPrefillComplete -- Handle the prefill complete event from PE.
 *
 * @param
 *      hPBC -- handle to playback control engine private data
 *      tInput -- PE Input pin that is done with prefill
 *
 * @retval
 *      PLAYCTRL_STATUS
 */
PLAYCTRL_STATUS PbcPLCtrlPrefillComplete(PBC_HANDLE *hPBC, PE_ISTREAMCTRL_INPUT tInput)
{
    BOOLEAN fAllPrefillComplete = TRUE;

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

    if (hPBC == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlPrefillComplete: NULL pointer!\n"));
        return (PLAYCTRL_NULL_POINTER);
    }

    /* Mark this PE input as done waiting for prefill */
    hPBC->fWaitingPrefill[tInput] = FALSE;

    /*
     * If currently on a still, do not want to start decode.
     */
    if (hPBC->ulStillTime == 0)
    {
        /* Check for any PE input pins waiting for prefill */
        for (int i = 0; i < MAX_PE_INPUTS; i++)
        {
            if (hPBC->fWaitingPrefill[i] == TRUE)
            {
                fAllPrefillComplete = FALSE;
                break;
            }
        }

        /* If all PE input pins are done waiting for prefill, then start decode */
        if (fAllPrefillComplete == TRUE)
        {
            ULONG out_msg[4];

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

            DBGPRINT(DBG_ON(DBG_TRACE), ("PbcPLCtrlPrefillComplete: Calling PEiStreamCtrlRun()\n"));
            if (PEiStreamCtrlRun(hPBC->hPE) != PE_SUCCESS)
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlPrefillComplete: PEiStreamCtrlRun() FAILED!\n"));
                return (PLAYCTRL_FAILURE);
            }
        }
    }

    DBGPRINT(DBG_ON(DBG_TRACE), ("PbcPLCtrlPrefillComplete: EXIT\n"));

    return (PLAYCTRL_SUCCESS);
}

/**
 * PbcPLCtrlInitRandomShuffle -- Initialize random/shuffle state.
 *
 * @param
 *      ubFirstPlayitem -- first playitem being presented
 *
 * @retval
 *      random playitem to start with
 */
uint16  PbcPLCtrlInitRandomShuffle(void)
{
    USHORT usNumPlayitems;
    uint16 uiPlayitemId;

    /* Get number of playitems in current playlist */
    MPLSGetNumberOfPlayItems(&usNumPlayitems);

    /* Initialize count and current index to 0 */
    RandomShuffle.usCount           = 0;
    RandomShuffle.usCurrentIndex    = 0xFFFF;

    /* Set number of available playitems */
    RandomShuffle.usNumberAvailable = usNumPlayitems;

    /* Initialize both lists */
    memset( (void *)RandomShuffle.usAvailableList, 0xffff, MAX_NUMBER_PLAYITEMS);
    memset( (void *)RandomShuffle.usPlayedList, 0xffff, MAX_NUMBER_PLAYITEMS);

    /* Load list of available playitems */
    for (UBYTE i = 0; i < RandomShuffle.usNumberAvailable; i++)
    {
        RandomShuffle.usAvailableList[i] = i;
    }

    /* set playitem id to random number between 0 and number of available playitems */
    srand( (unsigned int)time(NULL) );
    uiPlayitemId = RandomShuffle.usAvailableList[rand() % RandomShuffle.usNumberAvailable];

    return (uiPlayitemId);
}

/**
 * PbcPLCtrlGetNextPlayitem -- Get next playitem of a playlist.
 *
 * @param
 *      hPBC     -- handle to playback control engine private data
 *      ubCurrPi -- the current playitem (return the playitem after this one)
 *
 * @retval
 *      if next playitem exists, playitem id
 *      if next playitem does ont exist, INVALID_PLAYITEM.
 */
uint16 PbcPLCtrlGetNextPlayitem(PBC_HANDLE *hPBC, uint32 uiPlayitemID)
{
    APPINFOPLAYLIST_TABLE   *pPLAppInfo     = NULL;
    uint16                  uiPlayitemId    = INVALID_PLAYITEM;
    uint16                  uiNumPlayitems;

    if (hPBC != NULL)
    {
        /* Get playlist info */
        MPLSGetAppInfo(&pPLAppInfo);

        /* Get number of playitems in current playlist */
        MPLSGetNumberOfPlayItems(&uiNumPlayitems);

        /* Check playlist playback type (sequential, random, or shuffle) */
        if (pPLAppInfo->PlayList_playback_type == MPLS_SEQUENTIAL_PLAYLIST)
        {
            /* Next playitem is sequentially following/preceding the current playitem */
            uiPlayitemId = (uint16)(uiPlayitemID + (hPBC->fReverse ? -1 : 1));

            /* Check that next playitem id is valid */
            if (uiPlayitemId >= uiNumPlayitems)
            {
                uiPlayitemId = INVALID_PLAYITEM;
            }
        }
        else
        {
            /*
             * If current playitem has not already been played once (and then skip prev happened),
             * then randomly select the next playitem.  Otherwise, the next playitem is in
             * the list of played playitems.
             */
            if ( (RandomShuffle.usCount == (RandomShuffle.usCurrentIndex + 1) ) && (hPBC->fReverse == 0) )
            {
                /* Random or Shuffle, so check if playback count has been reached */
                if ( (RandomShuffle.usCount != pPLAppInfo->playback_count) && (RandomShuffle.usNumberAvailable > 0) )
                {
                    /* set playitem id to random number between 0 and number of available playitems */
                    srand( (unsigned int)time(NULL) );
                    uiPlayitemId = RandomShuffle.usAvailableList[rand() % RandomShuffle.usNumberAvailable];
                }
            }
            else
            {
                /* Next playitem is in list of played playitems (if it has been played, else INVALID_PLAYITEM) */
                uiPlayitemId = RandomShuffle.usPlayedList[RandomShuffle.usCurrentIndex + (hPBC->fReverse ? -1 : 1)];
            }
        }
    }

    return (uiPlayitemId);
}

/**
 * PbcPLCtrlGetPrevPlayitem -- Get previous playitem of a playlist.
 *
 * @param
 *      hPBC -- handle to playback control engine private data
 *
 * @retval
 *      if prev playitem exists, playitem id
 *      if prev playitem does not exist, INVALID_PLAYITEM.
 */
uint16 PbcPLCtrlGetPrevPlayitem(PBC_HANDLE *hPBC, uint32 uiPlayitemID)
{
    APPINFOPLAYLIST_TABLE   *pPLAppInfo     = NULL;
    uint16                  uiPlayitemId    = INVALID_PLAYITEM;
    uint16                  uiNumPlayitems;

    if (hPBC != NULL)
    {
        /* Get playlist info */
        MPLSGetAppInfo(&pPLAppInfo);

        /* Get number of playitems in current playlist */
        MPLSGetNumberOfPlayItems(&uiNumPlayitems);

        /* Check playlist playback type (sequential, random, or shuffle) */
        if (pPLAppInfo->PlayList_playback_type == MPLS_SEQUENTIAL_PLAYLIST)
        {
            /* Previous playitem is sequentially preceding/following the current playitem */
            uiPlayitemId = (uint16)(uiPlayitemID - (hPBC->fReverse ? -1 : 1));

            /* Check that prev playitem id is valid */
            if (uiPlayitemId >= uiNumPlayitems)
            {
                uiPlayitemId = INVALID_PLAYITEM;
            }
        }
        else
        {
            /* Check if there is a previous playitem in the played list */
            if (RandomShuffle.usCurrentIndex != 0)
            {
                /* Previous play

⌨️ 快捷键说明

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